CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Understanding the SPI in context with CCS coding

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

Re: Thank you for the details
PostPosted: Fri Nov 04, 2011 2:54 am     Reply with quote

RckRllRfg wrote:
Thank you very much for the responses. These are details that puts it all into perspective.

As for the method, I was fortunate to find code in the CCS driver directory called mcp4921. It is the exact same method of SPI handling that is used by the mcp4822. I like this method because it does give me full control of the signal switching and more importantly, the timing of the signals.

All the best to you in your endeavors,

RckRllRfg


I've used the mcp4822 or at least I inherited code that did. I rewrote the "driver" for it. I did a lot of tidying up. We use setup_spi() and spi_read() and spi_write(). It all works no problem. Certainly simpler and way more portable than direct control. You might be attracted to the idea of having "full control", but it leads to non-portable code and is more difficult to develop.

RF Developer.

Here's our driver. Note I've had to consider hardware timing at differing processor speeds. This runs at both 10MHz and 40MHz on PIC18F8585.

Code:

/*
write_mcp4822.c

This function writes two 12-bit words to a Microchip MCP4822 DAC and then
simultaneously latches the data to the outputs.
The two 16-bit words passed to the function are limited to 0xFFF to avoid any
rollovers.
*/


// Use with:
// 10MHz operation at 40MHz processor clock   
// setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_XMIT_L_TO_H|SPI_CLK_DIV_4);
// Typical Defines for the select pin and latch
// #define DAC_SELECT PIN_C1
// #define latch_dac PIN_C2

void write_mcp4822(int16 DAC_SELECT, int16 value_1, int16 value_2)
{
   // Prepare the first value
   if(value_1 > 0x0FFF)            //Limit value of DAC A value with no rollover
   {
      value_1 = 0x0FFF;
   }

   // Set control bits
   bit_clear(value_1, 15);           // Write to DAC A
   bit_clear(value_1, 13);            // Output gain = 2
   bit_set(value_1, 12);            // Output enabled
   
   //write the first value. The MCP4822 treats its two
   // channels effectively as two DACS. We have to issue TWO
   // SPI sequences. We cannot send one long one with both
   // sets of data.
   output_low(DAC_SELECT);            //select DAC IC /CS
   spi_write(make8(value_1,1));      //write upper byte
   spi_write(make8(value_1,0));      //write lower byte
   output_high(DAC_SELECT);         //unselect DAC /CS   
   
   // Prepare the second
   if(value_2 > 0x0FFF)               //Limit value of DAC B value with no rollover
   {
      value_2 = 0x0FFF;
   }

   // Set control bits
   bit_set(value_2, 15);            // Write to DAC B
   bit_clear(value_2, 13);            // Output gain = 2
   bit_set(value_2, 12);            // Output enabled

   output_low(DAC_SELECT);            //select DAC IC /CS
   spi_write(make8(value_2,1));      //write upper byte
   spi_write(make8(value_2,0));      //write lower byte
   output_high(DAC_SELECT);         //unselect DAC /CS

   // Latch both values onto the analogue outputs
   output_low(latch_dac);
   // At 10MHz there is sufficient time between instructions to
   // meet the MCP4822's timing requirements without any additional
   // delays. The analogue output changed when we drove the latch
   // low. All we need to do now is bring it high again.
   
   // That was true at 10MHz, but not at 40MHz! So we have to add a few NOPs
   // to ensure correct timing. 1 "wait state" gives 200ns at 40MHz, or 500ns at 10MHz                             
   delay_cycles(1);
   output_high(latch_dac);
}
RckRllRfg



Joined: 20 Jul 2011
Posts: 60

View user's profile Send private message

Much Appreciated.
PostPosted: Sat Nov 05, 2011 12:04 am     Reply with quote

RF_Developer -

This is much appreciated. I was able to get the code example provided by CCS up and running for both channels of the mcp4822. So far, so good. However, we need to update this information 30,000 times a second (using a 20MHz clock), so I know that my code will need to be tight. I've been chasing other aspects of the firmware code, so I will need to revisit this soon.

Thank you for the guidance.

Regards -

RckRllRfg
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group