Important update: Arm Announces End of Life Timeline for Mbed. This site will be archived in July 2026. Read the full announcement.
Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
SSP/SPI communication
Here's a basic framework. It adds a start marker, end marker and length to each packet to help keep things in sync. This does assume that the message size will never be over 255 so we can use a single byte for length.
Data that comes in is handled by an interrupt and put into a temporary buffer. Once the whole message is received it is copied into a new buffer for the main background loop to process. This frees up the temporary buffer so that a new message can start to arrive while the first one is getting processed. All the main loop needs to do is check if there is a message waiting, it will only ever get complete messages+.
The main loop must flag that it has finished processing the message before the next one has finished arriving or the message will be lost and the overflow indicator set.
Message transmission is done by calling the transmit function with a char array and length. This automatically adds start, end and length information to the message when sending it.
+There is a chance of a garbled message getting through, adding a checksum would reduce this significantly.
// max size of a message we could want to send/receive must be under 254 since we only use 1 byte for length. #define bufferSize 64 // messages should start and end with these as a sanity check that they are valid. #define messageStartMarker 'S' #define messageEndMarker 'E' // serial port to use serial dataconnection(tx,rx); // variables to hold incoming messages that are ready for the main loop to look at. char dataReadyBuffer[bufferSize]; // data buffer volatile int dataReadySize = 0; // size of data (-1 for an error in Rx), set to 0 to indicate buffer is free. volatile bool overflow = false; // data overflow indicator. // data rx interrupt void ondataRx(void) { static char dataInBuffer[bufferSize]; // buffer to put data into as it arrives static enum eRxState {waitingStart, waitingLen, inData, waitingEnd} rxState = waitingStart; // current rx state static int expectedBytes = -1; // expected message length static int dataCount = 0; // current message length char byteIn; while (dataconnection.readable()) { // while there is data in the port byteIn = dataconnection.getc(); // read data switch (rxState) { // process data depending on the current state default: case waitingStart: if (byteIn == messageStartMarker) rxState = waitingLen; break; case waitingLen: expectedBytes = byteIn; rxState = inData; dataCount = 0; break; case byteIn: dataInBuffer[dataCount] = byteIn; dataCount++; if (dataCount == expectedBytes) // got all the data rxState = waitingEnd break; case waitingEnd: if (byteIn == messageEndMarker) { if (dataReadySize == 0) { // main loops buffer is available memcpy(dataReadyBuffer,dataInBuffer,dataCount); // copy the rx data to the main loops buffer. dataReadySize = dataCount; // indicate that the buffer has data in. } else // buffer isn't available overflow = true; } else { // didn't get the expected message end marker dataReadySize = -1; } rxState = waitingStart; break; } // end switch } //end while } // send a message. Automatically adds the start, length and end markers. void sendMessage(char *data, int len) { dataconnection.putc(messageStartMarker); dataconnection.putc(len); for (int i = 0; i<len; i++) { dataconnection.putc(*(data+i)); } dataconnection.putc(messageEndMarker); } main() { serial.attach(ondataRx); // attach rx interrupt. while (true) { if (dataCount != 0) { // will be changed when there is data ready if (dataCount < 0) { // -1 indicates an error (didn't get the end marker at the expected place) // rx error. handle (or ignore) } else { // got a valid packet // dataReadyBuffer contains a valid message of size dataReadySize // process it in whatever way you see fit. } dataCount = 0; // indicate that we are done with the data and it can be over written. if (overflow) { // indication that a second message arrived and was lost while we were processing that one. overflow = false; } } }
Hi all,
I want to accomplish the following task. I want to make two mcu's talk together through the SSP/SPI protocol ideally with interrupts.
Can someone help me with the pseudocode for the master and the slave?
I get totally confused when having to program two mcu's especially when factoring in also interrupts and I am hoping you could help me break it down into smaller steps.
Is there an easy way to think about implementing interrupts? E.g. I have heard someone say that thinking about it as a state machine is easier but I couldn't understand how that could help me.
Cheers everyone