Hi Marco
I simply control the CS line using an output with the KL's SPI:
_CLEARBITS(E, PORTE_BIT4); // assert the CS line
write/read a number of bytes
_SETBITS(E, PORTE_BIT4); // negate the chip select line
I see no reason why your KL driver should freeze in the last while - as pointed out previously, make sure that this is not due to the debugger reading its status register and clearing the flag that the code is waiting for.
In the case of the DSPI you can slightly improve performance by making use of the 4 deep FIFO. This allows 4 bytes to be sent at maximum speed (no space between them) but you will still need to wait on the final byte to be completely read in before extracting the final rx data byte. In your case, when reading the manufacturer's ID of an SPI Flash device, you can do.
SPI0_PUSHR = (CMD_READ_ID | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(1)); // queue 4 writes, controlling the CS line to be asserted at the start and negated after transmission
SPI0_PUSHR = (0xFF | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(1));
SPI0_PUSHR = (0xFF | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(1));
SPI0_PUSHR = (0xFF | SPI_PUSHR_PCS(1));
while ((SPI0_SR & SPI_SR_RXCTR_MASK) < (3 << 4)); // wait until 3 bytes have been received
device_id2 = SPI0_POPR; // 3 dummy reads
device_id2 = SPI0_POPR;
device_id2 = SPI0_POPR;
while ((SPI0_SR & SPI_SR_RXCTR_MASK) == 0); // wait until the final byte has been received
device_id2 = SPI0_POPR; // the result
It is also possible to wait for all 4 bytes, read 3 dummy ones and then keep the fourth. The above will just be two or three instructions faster (a few ns...) since the 3 byte flush is performed during the fourth byte transmission/reception.
Since the SPI in the KL doesn't have FIFOs the techniques to improve performance are:
1. Send the first byte.
2. Wait for the TX status to indicate that a further byte can be written. This is before the Rx byte has been received (maybe after about 2 bits transmission - I didn't measure this though).
3. Send the next byte (if there is further data to be sent)
4. Wait for the Rx and read when it is ready.
5. Go to 2.
Or
Configure DMA for Tx and Rx. Let the DMA controller send and receive and wait until the DMA controller informs that the requested number of bytes have been transmitted and received. Then read the 4th byte from the DMA Rx buffer in the example case.
Regards
Mark
P.S. I use the DSPI and SPI for SD card and AT45DBxxx, ST25P(E)xxx, SSTxxx SPI Flash.