We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hey, Thinking that the SSP and SPI interfaces are the same, I wrote the code for SSP slavemode interrupt. But then found out that there is a difference. The CS(SSEL) line in SPI remains low for whole frame transfer, in SSP but it toggles after each frame (a frame = 4-16bits _configurable_) in SSP. (SPI frame can be of 'n' no of bytes) So at the master, i modified the CS to act as GPIO and toggle the line after every byte transfer.
Now the problem is that if i process interrupt after receiving of each data byte the code generates an os_error. Hence (referring an example code) i had to implement the data transfer in a while loop as in the code below:
while( (SSPx->SR & SSP_SR_RNE) || (SSPx->SR & SSP_SR_TFE) || (dataCfg->tx_cnt != dataCfg->length)) { tmp = SSP_ReceiveData(SSPx); if(tmp == SPI_SOF) { dataCfg->rx_cnt = 0; dataCfg->tx_cnt = 0; dataCfg->status = SPI_STATUS_SOF; } if(dataCfg->tx_data == NULL) { SSP_SendData(SSPx, 0xFF); dataCfg->tx_cnt++; } else { SSP_SendData(SSPx, (*(uint8_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt))); dataCfg->tx_cnt++; } // Store data to destination //if (dataCfg->rx_data != NULL) { *(uint8_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint8_t) tmp; dataCfg->rx_cnt++; } // Check error if ((stat = SSPx->RIS) & SSP_RIS_ROR) { // save status and return dataCfg->status = stat | SSP_STAT_ERROR; return; } }
os_error = 2, which indicates that the interrupt occurance is too fast. CPOL = 0, CPHA = 1. performing the data transfer in while loop, causes loss of synchronization. Cant figure out how to solve this. The master clock frequency = 250KHz. Master is a microchip IC (whose code worked well with SPI protocol of LPC1768).
Note that you can use FIFO to reduce the number of interrupts. The SSP is way more capable than the very stupid SPI device.
And if you are sending messages, then there is no reason to inform the OS about each individual word transfer - it's enough to send an event when the transfer ends, to let the relevant task pick up the result and consider what new message to send.
If you are the receiver, then you can consider waiting with informing the thread until the slave select gets deactivated - unless you have a protocol that is doing the bad thing of keeping slave select active and sending both a question and expecting the slave to think and prepare a response on-the-fly within the same slave-select cycle.
It's harder to be the slave, but the chip is able to run several MBit/s as slave.
Thank you for clearing the air about FIFO. I have implemented the ISR for SSP. The protocol is a bit complicated. The slave sends the answer for the previous question (asked in previous SSEL cycle) that the master had asked, in the current SSEL cycle. If there was any communication failure, it is indicated by the NACK bytes transmission instead of the answer.
Then you could have the pin you connected slave select to generate a pin-change interrupt - or an external interrupt if the relevant pin happens to have EINTx support.
So SSP interrupt could just send out data and retrieve data (multiple words handled in each interrupt thanks to FIFO), interfacing with suitably large ring buffers. And the pin-change interrupt creates an event to report "transer done: process input and prepare new output".