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 support@ccsinfo.com

'876 won't receive SPI data (as Master)

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







'876 won't receive SPI data (as Master)
PostPosted: Wed Nov 21, 2001 1:45 pm     Reply with quote

I'm attempting to read data from an SPI A/D (MAX189). The PIC is in Master mode, and transmits SPI data fine (I'm sending data to a D/A as well), but when I use data=spi_read() to fetch a byte from the A/D, nothing happens! The clock line doesn't budge. I tried passing trash to spi_read() in an effort to wake it up (p 61 manual), and this did indeed trigger SCLK. Now the A/D faithfully provides the data onto SDI, but the PIC refuses to read it. Help!

Applicable code segments:

/* Initialize Registers */
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi( spi_master | spi_h_to_l | spi_clk_div_64 ); // 125kbit clock rate (8Mhz/64)
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
/* Initialize both CS lines high for SPI bus */
output_bit( PIN_B1, 1);
output_bit( PIN_B2, 1);
...
int H, L;
output_bit( PIN_B1, 0); // Bring ADC CS low, ADC starts to sample
delay_us(20); // conversion takes 8.5us
H = spi_read(83); // passing random data so that PIC will activate the clock line (but it still doesn't read)
L = spi_read(83);
output_bit( PIN_B1, 1); // Bring ADC CS high

Thanks in advance for any assistance!
- Ryan Barton
___________________________
This message was ported from CCS's old forum
Original Post ID: 1277
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: '876 won't receive SPI data (as Master)
PostPosted: Wed Nov 21, 2001 2:09 pm     Reply with quote

This is for reading 24 bits from a LTC2400 via an SPI interface and could be easily modified for fewer bits. This portion of code only reads the SPI port when the conversion is complete and can thus be placed in a primary services loop.

output_low(PIN_A0);
delay_cycles(5); // give time for pin A1 to toggle
if (input(PIN_A1))
{
output_high(PIN_A0);
goto CheckSerialPort;
}
output_high(PIN_A3);
ADCbuffer[0]=0;
ADCbuffer[1]=0;
ADCbuffer[2]=0;
for (shiftbit = 1; shiftbit <= 26; shiftbit++)
{
output_high(PIN_A2);
shift_left(ADCbuffer,3,input(PIN_A1));
output_low(PIN_A2);
}
output_high(PIN_A0);
CheckSerialPort:
___________________________
This message was ported from CCS's old forum
Original Post ID: 1278
Ryan Barton
Guest







Re: '876 won't receive SPI data (as Master)
PostPosted: Wed Nov 21, 2001 2:19 pm     Reply with quote

thx. I was just thinking that bit-banging SCI wouldn't be too hard. The only disadvantage is throwing away my working SCI transmit code and having to rebuild it from scratch (all 3 ports would need to be defined as general I/O). I'd like to find a solution using the built-in functions, but if I get peeved enough, brute-force is always an option...
- Ryan
___________________________
This message was ported from CCS's old forum
Original Post ID: 1279
Ryan Barton
Guest







kludge fix
PostPosted: Wed Nov 21, 2001 3:18 pm     Reply with quote

After researching the '87x manual and looking at the assembly produced, I found the problem: data=spi_read() simply copies the contents of the SSPBUF register to 'data'. In Slave Mode, the compiler expects you to check for data (spi_data_is_in) before grabbing it. BUT... when in Master Mode, there's no point in checking since the PIC controls SCLK, and without running SCLK, no data comes in!
Kludged solution: Drop to assembly, throw something at SSPBUF, come back. This starts the SCLK transitions (and starts to clock in the data!) NOW poll spi_data_is_in until the byte has arrived, and then use spi_read() to get it. Sheesh!

Code sample (that works!):

int H, L;
output_bit( PIN_B1, 0); // Bring ADC CS low, ADC starts to sample
delay_us(20); // conversion takes 8.5us
#ASM
movlw 0
movwf 0x13 // write trash to SSPBUF to activate SPI clocking (PIC datasheet p70)
#ENDASM
while(spi_data_is_in()==0) {} // wait till byte is received
H = spi_read();
#ASM
movlw 0
movwf 0x13 // write trash to SSPBUF to activate SPI clocking (PIC datasheet p70)
#ENDASM
while(spi_data_is_in()==0) {} // wait till byte is received
L = spi_read();
output_bit( PIN_B1, 1); // Bring ADC CS high

One could use spi_write to force something out (to avoid the drop to assembly). Does anyone know of a more elegant solution than this? (just curious)
- Ryan Barton
___________________________
This message was ported from CCS's old forum
Original Post ID: 1280
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: kludge fix
PostPosted: Wed Nov 21, 2001 3:59 pm     Reply with quote

BUT... when in Master Mode, there's no point in checking since the PIC controls SCLK, and without running SCLK, no data comes in!
:=Kludged solution: Drop to assembly, throw something at SSPBUF, come back. This starts the SCLK transitions (and starts to clock in the data!) NOW poll spi_data_is_in until the byte has arrived, and then use spi_read() to get it.
------------------------------------------

I think you can do this with spi_read(0). Check the Version 3
manual for spi_read().
___________________________
This message was ported from CCS's old forum
Original Post ID: 1281
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