Handling 64-bit data through spi communication for 8-bit PIC

NorthGuy

Joined Jun 28, 2014
611
If you're not sure what your receive, connect SDI (MISO) to VDD and run your program. You will receive 0xff. Then connect it to VSS and repeat. You will receive 0x00. Then connect it to SDO (MOSI). You will receive a copy of what you transmit. If that's the case, then your code receives correctly what's on the line.
 

Thread Starter

sarvanan

Joined Aug 8, 2016
45
Hi NorthGuy,

Thanks for the very useful info. A very basic question, When you talk about connecting SDI to VDD or VSS or SDO, i think you mean physical connection or is there a S/W way of doing it means by assigning values?

Thanks & regards,
Sarvanan.
 

Thread Starter

sarvanan

Joined Aug 8, 2016
45
Hi NorthGuy and other learned members,

I am able to send and receive data through spi communication, Thanks. But even if chip select is 0 or 1 in both cases I am getting data from other controller. Just writing pins and their ltach, tris assigned values to find out if they are correct.
1. chip select is inverted and connected to RA0 //This is output as pic is master.
2. INT_LINE is also inverted and connected to RB0 //This is input as pic is master other controller is slave.
3. SCK connected to RC3 //output
4. SDO connected to RC5 //output
5. SDI – connected to RC4 //input
Here is the value i assign:
TRISCbits.TRISC3=0; //SCK as output
TRISCbits.TRISC5=0; //SDO as output
TRISCbits.TRISC4=1; //SDI as input
TRISAbits.TRISA0 = 0; // chip select is output
TRISBbits.TRISB0 = 1; //INT_LINE as Input
SSPSTAT = 0x00;
SSPCON1 = 0x20; // FOSC/4 == (32/4) = 8 MHZ
SSPADD = 0x00;
LATAbits.LATA0 = 0; // Chip select --- Is this correct as 1 also works?
exchange8bitdata( data)
After each 16 bit word the other controller is indicating a received word by pulling the /INT_LINE logic low. As soon as the other chip is ready to receive the next 16 bit word /INT_LINE is pushed high again.
So if(PORTBbits.RB0 == 0) // so this inverted line indicate transfer data otherwise wait.
I need to do above check once 16-bit data is transferred.
Insert 1 us delay __delay_us(1);
Then LATAbits.LATA0 = 1; // to unselect Chip select --- Is this correct as 0 also works?

Please let me know if I have set the different registers correctly? Do i need anymore settings?

Thanks & regards,
Sarvanan.
 

NorthGuy

Joined Jun 28, 2014
611
Please let me know if I have set the different registers correctly? Do i need anymore settings?
RB0 has an analog function on it, so you need to set the corresponding ANSEL bit to 0.

Looks good in theory (except that you send 8 bit instead of 16, but I'd take it's not the real code). Does it work in practice?
 

Thread Starter

sarvanan

Joined Aug 8, 2016
45
Thanks NorthGuy,

I will make the change.
I am sending 8 bit data at a time. I have to send total 64-bit data having four 16-bit words. As pic16lf1939 can send 8-bit only, I am planning to run the loop 8 times. One logical issue is that other controller once gets 16-bit then it will pull the INT_LINE to low and once its high then only next 16-bits(8-8 bits ) wold be sent or received by PIC.
Do you have any idea how to achieve this? Here is my code:

  1. uint8_t SPI_Exchange8bit(uint8_t data)
  2. {
  3. // Clear the Write Collision flag, to allow writing
  4. SSPCON1bits.WCOL = 0;
  5. SSPBUF = data;
  6. while(SSPSTATbits.BF == SPI_RX_IN_PROGRESS)
  7. {
  8. }
  9. return (SSPBUF);
  10. }

  11. uint8_t SPI_Exchange8bitBuffer(uint8_t *dataIn, uint8_t bufLen, uint8_t *dataOut)
  12. {
  13. uint8_t bytesWritten = 0;
  14. if(bufLen != 0)
  15. {
  16. if(dataIn != NULL)
  17. {
  18. while(bytesWritten < bufLen)
  19. {
  20. if(dataOut == NULL)
  21. {
  22. SPI_Exchange8bit(dataIn[bytesWritten]);
  23. }
  24. else
  25. {
  26. dataOut[bytesWritten] = SPI_Exchange8bit(dataIn[bytesWritten]);
  27. }
  28. bytesWritten++;
  29. }
  30. }
  31. else
  32. {
  33. if(dataOut != NULL)
  34. {
  35. while(bytesWritten < bufLen )
  36. {
  37. dataOut[bytesWritten] = SPI_Exchange8bit(DUMMY_DATA);
  38. bytesWritten++;
  39. }
  40. }
  41. }
  42. }
  43. return bytesWritten;
  44. }
Let me know how can I check INT_LINE after 16-bit (not after 8-bit) and put a 1us delay as I am sending 8-bit at a time.

Thanks & regards,
Sarvanan.
 

NorthGuy

Joined Jun 28, 2014
611
Do you have any idea how to achieve this?
Just straightforward:

- CS low
- exchange 8 bits
- exchange another 8 bits
- wait for INT
- continue sending
- CS high when done

CS handling may change depending on how the slave wants it.

If something doesn't work, it is a good idea to tell what's not working. Remember, people on the forum only know what you tell them, no more.
 
Top