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

Thread Starter

sarvanan

Joined Aug 8, 2016
45
Hi,

How to send and receive 64 bit data using spi communication considering 8-bit pic16 controller.

Let say implementation of spi communication between 8 bit PIC16 working at 32 MHZ with another micro controller has to be done in C language using xc8.
pic16 will send command in 64-bit data format which will contain 4 arguments i.e., 16-bit fixedVal1, 16-bit fixedVal2, empty 16-bit val3, empty 16-bit val4.
Another controller will send the response in the form of the 64-bit data format which will contain again 4 arguments having same 16-bit fixedVal1,
same 16-bit fixedVal2, but newly filled 16-bit val3, and newly filled 16-bit val4.

Let me know how to store the received values val3 and val4 in the pic16 without loosing any data. How to use chip select, sck, sdo and sdi lines considering port and tris registers?

Please help.

Thanking you,
Sarvanan.
 

Papabravo

Joined Feb 24, 2006
21,228
You have some choices. If you want to use the onboard SPI hardware then you must break the transmission and reception up into eight 8-bit bytes. SPI is actually an exchange between a producer device and a consumer device. Each transaction sends and receives 8 bits. So the data coming back cannot depend on the data going out. SPI doesnt work that way.

The other choice is to ignore the on board hardware and bit-bang the whole thing with 64 bit frames. 64 bits out and 64 bits in.

When handling data in larger than 8 bit size you can send and receive the most significant byte or the least significant byte first. When storing them in the file you can put them in RAM in either order. You pick a starting address and you either increment or decrement your address pointer.
 

Thread Starter

sarvanan

Joined Aug 8, 2016
45
Hi Papabravo,

Thanks for the help.
I need to send continuously 16 bit and wait untill the interrupt line is low again so that next 16-bit can be transferred. In this way total 64-bit needs to be sent.
Same way 64-bit needs to be received in packets of16-bits seeing the interrupt line.
Could you please tell how to use SDI, SDO and CS lines and perform sending and receiving in this case. Just a pseudo code can help.

Thanks & regards,
Sarvanan.
 

shteii01

Joined Feb 19, 2010
4,644
You said you have 8 bit pic.
Do you have a place that can receive and hold 16 bit string?

The way I was taught about micros is that received data arrives into a register. Then user, you, move it for storage to memory.

So. Do you have a register that is 16 bit, that can receive 16 bit string and then you move that string from that register to memory?
 

Papabravo

Joined Feb 24, 2006
21,228
If you are using the hardware SPI in a midrange PIC you don't get to select the data format. It is 8 bits at a time. Once the hardware is configured the process looks like:
  1. Take CS* for the desired peripheral low.
  2. Write 8 bits of data to the Transmit Data Register.
  3. Wait for the data to be transmitted and the Receive Data Register Flag to be set.
  4. Read the 8 bits of data from the Receive Data Register.
  5. Take CS* for the desired peripheral high.
  6. Store the 8 bits of data from the Receive Data Register into an array of bytes in RAM.
  7. Move the Address Pointer to the next available RAM location.
For 64 bits you would do steps 1-7 a total of eight times.
If you tell us which PIC you are using and give us a link to the datasheet we can be more specific.
 

Thread Starter

sarvanan

Joined Aug 8, 2016
45
Hi Papabravo,

Just wanted to add that at a time PIC will be sending 64-bit data or only receiving 64-bit data. It won't happen together. Then all 4 data of , 1 word(16-bit) will be used for different purposes.

Thanks & regards,
Sarvanan.
 

jpanhalt

Joined Jan 18, 2008
11,087
Hi Papabravo,

Just wanted to add that at a time PIC will be sending 64-bit data or only receiving 64-bit data. It won't happen together. Then all 4 data of , 1 word(16-bit) will be used for different purposes.

Thanks & regards,
Sarvanan.
SPI is always duplex, in the sense that you send a byte and a byte is received. Once you get started, you can send null bytes to receive sequential data and so forth.

John
 

John P

Joined Oct 14, 2008
2,026
I have some concerns about what has been proposed here, although it's absolutely standard SPI operation. What is going to happen if the master and slave disagree about which byte out of the 8 is being sent/received? And second, how do the master and and slave communicate to agree on whether the SPI link is being used to send data from master to slave, or slave to master? That second one wouldn't be an issue if data went both ways every time, but we're told that communication one way doesn't take place at the same time as communication the other way.

Maybe the first item could be dealt with by timing: both ends of the line are programmed to expect the data bytes to come with some maximum timeout between adjacent bytes, and if that's exceeded, the count is set back to zero. But the question of who's sending valid data is harder. Is the data itself somewhat predictable, so (for example) all 0x00's or all 0xFF's would be recognizable as dummy data? Then maybe the slave could signal the master "I have data to send", or the master could tell the slave "Next packet, send me your data". We haven't been told how this process is meant to work.
 

jpanhalt

Joined Jan 18, 2008
11,087
I think it is called burst read and burst write. So far, I have only encountered burst read (i.e., CSn is held low until the read is completed). The first byte sent is the starting address, then subsequent read addresses auto-increment. It is still an exchange of bytes. The master simply sends a null, so far as I know. That way the slave knows to send the next byte.

There might be other ways to do it, as my experience is quite limited compared to others here.

John
 

Papabravo

Joined Feb 24, 2006
21,228
Hi Papabravo,

Just wanted to add that at a time PIC will be sending 64-bit data or only receiving 64-bit data. It won't happen together. Then all 4 data of , 1 word(16-bit) will be used for different purposes.

Thanks & regards,
Sarvanan.
STOP! You have a fundamental misconception of how SPI works. Any further discussion is pointless until you apply yourself and come to an understanding of how things work. SPI is not really suited for a general purpose data exchange. You must think in terms of byte by byte transactions since that is how SPI was designed. If you insist on bending technology to your view of the universe then you need to seek an alternative. I recommend a full duplex serial port. That way you can roll your own protocol and make it behave the way you want it to. You might also try an onboard CAN network. You could configure 8-byte request response messages and use the CAN identifier field to identify the data.

Good Luck with that.
 

MrChips

Joined Oct 2, 2009
30,824
As John points out, SPI is duplex. You send and received on the same transaction.

Some SPI will send more than 8 bits at a time, maybe 16 or 32 bits. Check your datasheet.

You have to establish a master/slave relationship where one MCU is the master and another is the slave.
If you only have one slave then you don't have to worry about slave address/identification.

The master MCU asserts NSS (/CS) and controls the serial clock, SCLK. The master sends MOSI (SDO) and receives MISO (SDI) simultaneously. Byte synchronization is not an issue because NSS frames the data packet.

If your MCU has DMA the entire multi-byte data transfer can be done without requiring software intervention.
 

Papabravo

Joined Feb 24, 2006
21,228
You might be interested in the Serial Line Internet Protocol (RFC 1055). It is a general purpose method to send and receive binary data over ANY communications media. I have adapted this method to numerous applications. It is simple, flexible, easy to debug and it just plain WORKS.

https://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol
https://tools.ietf.org/html/rfc1055

To adapt to your situation on the 8-bit SPI

  1. Send {END}
  2. Send {DATA_FOR_SLAVE}
  3. Send {DATA1,DATA2,DATA3,DATA4,DATA5,DATA6,DATA7,DATA8}
  4. Send {END}
Each frame begins and ends with the same binary data. The {DATA_FOR_SLAVE} value is a statement by the master that what follows is eight data bytes. The SPI return data will be ignored and thrown on the floor.

To get data from the slave device
  1. Send {END}
  2. Send {DATA_FROM_SLAVE}
  3. Send {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
  4. Send {END}
Again, each frame begins and ends with with the same binary data. The {DATA_FROM_SLAVE} value is a statement by the master that what follows will be eight consecutive {NULL} characters whose value is irrelevant and has no meaning. However the returned data will be accumulated and stored by the master.

Naturally the send routine must detect the occurrence of {END} characters and {ESCAPE} Characters in the actual data and replace them with the appropriate escape sequences. Similarly, on the receiving end the escape sequences must be detected and replaced with the appropriate binary values.

Do you think this will fill the bill?

One other thing. It should be perfectly permissible to send multiple {END} characters without upsetting either the master or the slave device. You could even use this as a heartbeat function to detect a disconnect or other problem with the link.
 
Last edited:

Thread Starter

sarvanan

Joined Aug 8, 2016
45
If you are using the hardware SPI in a midrange PIC you don't get to select the data format. It is 8 bits at a time. Once the hardware is configured the process looks like:
  1. Take CS* for the desired peripheral low.
  2. Write 8 bits of data to the Transmit Data Register.
  3. Wait for the data to be transmitted and the Receive Data Register Flag to be set.
  4. Read the 8 bits of data from the Receive Data Register.
  5. Take CS* for the desired peripheral high.
  6. Store the 8 bits of data from the Receive Data Register into an array of bytes in RAM.
  7. Move the Address Pointer to the next available RAM location.
For 64 bits you would do steps 1-7 a total of eight times.
If you tell us which PIC you are using and give us a link to the datasheet we can be more specific.
Hi Papabravo,

I am new to controllers that's why had some confusions. I agree with the above proposed method. This would work as per requirement.
This needs to be done for PIC16LF1939-I/MV, working at 32MHZ. Here is the link for datasheet.
http://ww1.microchip.com/downloads/en/DeviceDoc/40001574C.pdf

Thanks & regards,
Sarvanan.
 

Papabravo

Joined Feb 24, 2006
21,228
Hi Papabravo,

I am new to controllers that's why had some confusions. I agree with the above proposed method. This would work as per requirement.
This needs to be done for PIC16LF1939-I/MV, working at 32MHZ. Here is the link for datasheet.
http://ww1.microchip.com/downloads/en/DeviceDoc/40001574C.pdf

Thanks & regards,
Sarvanan.
Got the datasheet. Now we can discuss your problem in more specific detail. I want you to succeed on this project.
 

Thread Starter

sarvanan

Joined Aug 8, 2016
45
Hi All Members,

So many members replied to my question. Thanks to all of them as it contributed in my understanding of the issue and also how spi works.
I am working on the some od the suggestions and will come back if i face any issue.

Thanks & regards,
Sarvanan.
 

John P

Joined Oct 14, 2008
2,026
Getting SPI to work is trivial, or ought to be. I don't think you're solving the difficult problems. Maybe this would work:

Make the master send out data bytes (and also receive data bytes, of course) at a fairly rapid rate, say 10K/second. Designate some value to be called "NULL", most likely 0x00 or 0xFF, but it could be anything. If either end of the line sees 9 NULLs in a row, that means the line is IDLE in that direction. The same protocol is used for data from slave to master, and from master to slave.

Valid data in either direction means that a character that is not NULL will be sent, followed by 8 data bytes and then at least 9 NULLs, causing a return to IDLE. The same value used as NULL may occur as data, and won't cause any problems.

Both units must examine every byte that arrives. NULLs are counted to determine whether the line is IDLE or not. If a transition from IDLE to not-IDLE occurs, the first byte (of 9) is discarded, and the following 8 bytes will be valid data. I think that's a robust way to send ordered packets in both directions without risking a counting mixup.
 
Top