I'm trying to interface 2 MAX7219 drivers using a 9s12. My problem is that when I send the data, the latch pulse is happening before the SPI transfer has been completed. https://i.sstatic.net/pIvR8.jpg
Attached picture shows the pulse happening while the SPI clock and data are still being sent in.
void MAX7219Init(void)
{
INT8U count =0;
setLow(PORTP, PIN6); /* Need to set low on startup */
for (count = 1; count <= 2; count++){ //Run twice to send data to 2 max7219
spimx(0x0F, 0xCD);
}
pulse(PORTP, PIN6);
while (1) ;
}
void spimx(INT8U address, INT8U data)
{
while((SPI0SR & SPTEF) == 0){} /*Wait for previous transmit */
SPI0DR = (INT8U)(address & 0b00001111); /*Initiate a transfer */
while((SPI0SR & SPIF) == 0){} /*Wait for new data */
while((SPI0SR & SPTEF) == 0){} /*Wait for previous transmit */
SPI0DR = data; /*Initiate a transfer */
while((SPI0SR & SPIF) == 0){} /*Wait for new data */
}
What could be causing this pulse to be early? I hope my question makes sense. Thanks
At the moment you send the pulse, the SPI is still transmitting data. You must wait until the SPI has completed all pending transfers, not just wait for the tranmit buffer being empty (I suppose the SPI is double-buffered: tx buffer plus shift register, this is very common).
So, either the SPI module has a status bit which signals "transmission complete" (on STM32 this is called "busy" with reversed signalling on SPI). Or, if there is no such flag, you should use a timer to wait for the proper number of clocks elapsed. (Start timer aftersending the last word to SPI with a timeout value >= the tranmit duration according to SPI clock and number of bits per transfer).
Ok, I had a close look and there is actually no "complete/busy/idle flag. So we have to wait for each bytes trasnmitted using the receive flag (see below)
void spimx(INT8U address, INT8U data)
{
SPI0DR = (INT8U)(address & 0b00001111); // send address
while ( !(SPI0SR & SPIF) ) ; // Wait until shifted
SPI0DR; // explaination below
SPI0DR = data; // send data
while ( !(SPI0SR & SPIF) ) ; // Wait until shifted
SPI0DR; // explaination below
// here the SPI is idle
}
Due to the bidirectional nature of SPI, if data has been received, the stored byte also has been transmitted. So no actual need to test for SPTEF. At the beginning, also no need as the SPI has been empty from the last call (see below for a warning).
To clear the SPIIF flag, we have to read the data register. As we do not need the data we just drop it (dummy read). Otherwise, the flag will stay set forever and the wait-loops will terminate instantly. And this will result in exactly the behaviour shown.
Note to use no other funcrtion writing to the SPI after initialization. Otherwise that has to conform to the same procedure.