Hi,
I have written a working interrupt driven SSI to communicate with my Winbond flash. Below is the pseudo code:
===========================================================================================
// Transfer data bytes between master and slave
ssi_tranfer fuction {
- pull SS low
- SSIIntEnable(SSI0_BASE, SSI_TXFF | SSI_RXFF | SSI_RXTO);
- Interrupt should start occurring here ...
- while loop, wait for SS line to be high (will be pulled high once the data transaction is completed in the ISR)
}
// The interrupt handler for SSI
SSI ISR {
Check and save the interrupt status then clear it
if (status & (SSI_RXFF | SSI_RXTO)) {
while (1) {
keep reading the RX FIFO
if RX FIFO empty, break the loop
if done receiving required data (RX byte count reaches 0), disable SSI_RXFF
}
if (all required data bytes has been transmitted and received) {
Pull SS high
}
}
if (status & SSI_TXFF) {
for loop (up to 8 times to fill up the TX FIFO) {
if done transmitting required data (TX byte count reaches 0), disable SSI_TXFF
if TX FIFO full, break the loop
}
}
}
============================================================================================
I will use an example to illustrate my problem, lets say when I want to read the device id and manufacturer id of the
winbond flash. The flash requires the master to send WB_READ_ID followed by 3 bytes of 0x00, then the flash will
spit out the device id + manufacturer id.
Below is a diagram to illustrate the transfer:
XX = don't care
// Transmitting 4 data bytes and expects two bytes of device id + manufacturer id
TX RX
WB_READ_ID XX
0x00 XX
0x00 XX
0x00 XX
// Master needs to drive clock to allow man_id and dev_id to be shifted out
0x00 man_id
0x00 dev_id
In order to read the device id + manufacturer id, my code will / should:
- Flag SSI_TXFF since the TX FIFO is initially empty
- Enters ISR (1st time)
- load up the 6 data bytes
- WB_READ_ID
- 0x00
- 0x00
- 0x00
- 0x00
- 0x00
- TX count reaches 0 meaning no more data to transmit
- Disable the TX interrupt
- Leaves ISR
- Flag SSI_RXFF as slave has received those 6 bytes and transmitted 6 bytes back to the master
- Enters ISR (2nd time)
- read the RX FIFO, 6 bytes
- XX
- XX
- XX
- XX
- man_id
- dev_id
- RX count reaches 0 meaning no more data to receive
- Disable RX interrupt
- pull SS HIGH
- leaves ISR
Breaks the while loop that is waiting for SS to be high in ssi_tranfer fucntion
program ends.
As one can see, according to the logic of my code, in this case, I should only enter the ISR two times. When
I step-debug my code(insert breakpoint in the ISR), I was able to see the program enter exactly twice. However,
when I do a full run, I get 3 ISR entries which is weird (I inserted a counter to keep the count of ISR entry, and I also
tried to toggle a gpio to monitor the entry / exit of ISR using logic analyzer).
Is there something that I am not understanding correctly about my code or the interrupt mechanism of cortex m4 ...etc?
Best Regards and Thanks in advance!
Jacky