Motherboard Forums


Reply
Thread Tools Display Modes

atmega2560 - LTC2440 SPI communication...need help troubleshooting

 
 
icabod8
Guest
Posts: n/a
 
      04-13-2012, 07:24 PM
New guy here trying to talk to an AD board via SPI. Was hoping someon
might help me troubleshoot.

I have an ATmega2560 attached to a STK600 development board. I'm trying t
get data off of a LTC2440cgn AD board. But all I get out is 0...

The AD board is 24 bit resolution, but produces a 32 bit value with th
data being in bits 5-28... so I figure first I need to read in 4 bytes fro
the AD via SPI. Then I combine 4 those four bytes into one and peel of
the data bits. Then I send the 8 most significant bits to LEDs to see i
I'm getting anything.

Here is my function to initialize the SPI...


void InitSPI(void)
{
//SPI is done through PORTB. SS is pin0, SCK is pin1, MOSI is pin2
DDRB = (1<<PB2)|(1<<PB1) | (1<<PB0); //Set MOSI, SCK, and SS output

//SPCR: SP Control Register...
SPCR = ( (1<<SPE)|(1<<MSTR) | (1<<SPR1) |(1<<SPR0)); // Enable SPI
Master, set clock rate fck/128
}


Here is my function to read 1 byte from the SPI...


uint8_t ReadByteSPI()
{
//writing data to the SPI data register to initiate transaction
SPDR = 0xFF; //Load dummy byte to SPI Data register

while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
return SPDR; //data register should now contain data from AD?
}


Here is my function to read in 4 bytes, and combine them and pull out th
data portion...


uint32_t ReadADCspi(){
//the LTC2440 transmits a 32 bit value
//so read 4 bytes into memory and construct it

//SELECT_ADC is defined as PORTB &= ~(1<<PB0)
//DESELECT_ADC is defined as PORTB |= (1<<PB0)

SELECT_ADC;
uint8_t a = ReadByteSPI();
_delay_us(100); //delay for next reading...do I need this?
uint8_t b = ReadByteSPI();
_delay_us(100);
uint8_t c = ReadByteSPI();
_delay_us(100);
uint8_t d = ReadByteSPI();
DESELECT_ADC;

uint32_t result = 0;
result = ((((((result | a) << 8) | b) << 8) | c) << 8) | d;

//ADC_MASK is 0b00011111111111111111111111100000
return (result & ADC_MASK)>>5; //data bits are 5-28

}


Finally, this is the main loop that calls ReadADCspi. I send the 8 mos
significant bits to LEDs to give me some indication if I'm getting any dat
out. Right now the AD board is connected to a voltage source that I ca
vary from 0-5 V. I would expect the LEDs to turn off and on based on th
voltage I'm sending, but they're only showing 0s.



InitSPI();

uint32_t output = 0;

//set up LEDs for test
DDRC = 0xFF; //sets PORTC for output
PORTC = 0b11111111;

while(1){
output = ReadADCspi();
PORTC = output>>16; //A# send the highest 8bits to LEDs to test output
_delay_ms(200); //delay to watch output
PORTC = ~0; //B# turn LEDs off briefly so I know Loop is executing
_delay_ms(100);
}


At this point I'm pretty stuck. I know the loop is running because th
LEDs flash off at the line marked B). They ALL turn on at line A) (ie
PORTC is all 0s which means output is zero always...)



---------------------------------------
Posted through http://www.EmbeddedRelated.com
 
Reply With Quote
 
 
 
 
linnix
Guest
Posts: n/a
 
      04-13-2012, 07:48 PM
On Apr 13, 12:24*pm, "icabod8" <jwebster8@n_o_s_p_a_m.gmail.com>
wrote:
> New guy here trying to talk to an AD board via SPI. Was hoping someone
> might help me troubleshoot.
>
> I have an ATmega2560 attached to a STK600 development board. *I'm trying to
> get data off of a LTC2440cgn AD board. But all I get out is 0...
>
> The AD board is 24 bit resolution, but produces a 32 bit value with the
> data being in bits 5-28... so I figure first I need to read in 4 bytes from
> the AD via SPI. *Then I combine 4 those four bytes into one and peel off
> the data bits. *Then I send the 8 most significant bits to LEDs to see if
> I'm getting anything.
>
> Here is my function to initialize the SPI...
>
> void InitSPI(void)
> {
> * * * * //SPI is done through PORTB. *SS is pin0, SCK is pin1, MOSI is pin2
> * * * * DDRB = (1<<PB2)|(1<<PB1) | (1<<PB0); //Set MOSI, SCK, and SS output
>
> * * * * //SPCR: SP Control Register...
> * * * * SPCR = ( (1<<SPE)|(1<<MSTR) | (1<<SPR1) |(1<<SPR0)); * *// Enable SPI,
> Master, set clock rate fck/128
>
> }
>
> Here is my function to read 1 byte from the SPI...
>
> uint8_t ReadByteSPI()
> {
> * * * * //writing data to the SPI data register to initiate transaction
> * * * * SPDR = 0xFF; * * * * * *//Load dummy byte to SPI Data register
>
> * * * * while(!(SPSR & (1<<SPIF))); * // Wait for transmission complete
> * * * * return SPDR; * * * *//data register should now contain data from AD?
>
> }
>
> Here is my function to read in 4 bytes, and combine them and pull out the
> data portion...
>
> uint32_t ReadADCspi(){
> * * * * //the LTC2440 transmits a 32 bit value
> * * * * //so read 4 bytes into memory and construct it
>
> * * * * //SELECT_ADC is defined as PORTB &= ~(1<<PB0)
> * * * * //DESELECT_ADC is defined as PORTB |= (1<<PB0)
>
> * * * * SELECT_ADC;
> * * * * uint8_t a = ReadByteSPI();
> * * * * _delay_us(100); * * *//delay for next reading...do I need this?
> * * * * uint8_t b = ReadByteSPI();
> * * * * _delay_us(100);
> * * * * uint8_t c = ReadByteSPI();
> * * * * _delay_us(100);
> * * * * uint8_t d = ReadByteSPI();
> * * * * DESELECT_ADC;
>
> * * * * uint32_t result = 0;
> * * * * result = ((((((result | a) << 8) | b) << 8) | c) << 8) | d;
>
> * * * * //ADC_MASK is 0b00011111111111111111111111100000
> * * * * return (result & ADC_MASK)>>5; * * * * * * * *//data bits are 5-28
>
> }
>
> Finally, this is the main loop that calls ReadADCspi. *I send the 8 most
> significant bits to LEDs to give me some indication if I'm getting any data
> out. *Right now the AD board is connected to a voltage source that I can
> vary from 0-5 V. I would expect the LEDs to turn off and on based on the
> voltage I'm sending, but they're only showing 0s.
>
> InitSPI();
>
> uint32_t output = 0;
>
> //set up LEDs for test
> DDRC *= 0xFF; //sets PORTC for output
> PORTC = 0b11111111;
>
> while(1){
> * * * * output = ReadADCspi();
> * * * * PORTC = output>>16; //A# send the highest 8bits to LEDsto test output
> * * * * _delay_ms(200); * * * * //delay to watch output
> * * * * PORTC = ~0; * * //B# turn LEDs off briefly so I know Loop is executing
> * * * * _delay_ms(100);
>
> }
>
> At this point I'm pretty stuck. *I know the loop is running because the
> LEDs flash off at the line marked B). *They ALL turn on at line A) (ie.
> PORTC is all 0s which means output is zero always...)
>
> ---------------------------------------
> Posted throughhttp://www.EmbeddedRelated.com


Just one thing i can think of, but might not be the problem. SS is
not automatic in SPI master mode. Might want to add PORTB |= (1<<SS)
to be sure.
 
Reply With Quote
 
 
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Silicon bug in Atmega2560? Meindert Sprang Embedded 5 06-12-2009 12:21 AM
porting FreeRtos to atmega2560 baranovus@gmail.com Embedded 1 08-04-2008 10:41 AM
Booting ATMEGA2560 ratemonotonic Embedded 3 10-20-2007 11:52 AM
Compaq Presario 7000 Troubleshooting Help CW Compaq 3 03-08-2006 11:54 PM
Need help troubleshooting - Latitude c800 Dennis Strouble Dell 2 11-11-2004 08:58 PM


All times are GMT. The time now is 12:40 AM.


Welcome!
Welcome to Motherboard Point
 

Advertisment