for more specifics here are two example functions of reading the Winbond W25Q128JV JEDEC ID.
1) Function ReadFlash. Framesize set to 32 bits. JEDEC ID command 0x9F and three dummy bytes all sent in one frame. Works fine, but can't increase the framesize indefinitely when comes time to read or write large blocks of data (but we confirmed the hardware is working). Also pic from analyzer showing correct read.
uint32_t JEDEC = 0x9F000000;
void FLASH::ReadJEDEC()
{
lpspi3.ReadFlash(JEDEC, 32); //pass JEDEC command + 3 dummy bytes directly
}
void HardwareSPI::ReadFlash(const uint32_t data, uint32_t framesize)
{
if (framesize != _framesize) // update TCR if new framesize
{
_framesize = framesize;
base->TCR = (base->TCR & ~LPSPI_TCR_FRAMESZ_MASK) | LPSPI_TCR_FRAMESZ(framesize - 1);
// wait for TCR update
while (LPSPI_GetTxFifoCount(base) != 0)
{
}
}
LPSPI_WriteData(base, data); // Write 32-bit data to the transmit data register (TDR)
while (LPSPI_GetTxFifoCount(base) > 0) {} // Wait for the transfer to complete
while (LPSPI_GetRxFifoCount(base) == 0) {} // Wait until there is data in the receive FIFO
uint32_t readData = LPSPI_ReadData(base); // Read the received data from the receive data register (RDR)
}

2) Function ReadFlashV2. Framesize set to 8 bits. JEDEC command sent as array of 4 bytes. The CONT bit (continuous transfer) not working, PCS never stays low, it always toggles high between bytes even when CONT used as described on page 2778 of the iMX RT1050 Reference Manual. How am I supposed to write or erase large blocks of data? Should I try disable hardware control of the PCS pin and set it up as GPIO? In this case I guess I would also have to handle PCS to CLK delays myself (using hardware PCS the API handles this already).
uint8_t JEDECV2[4] = {0xF9, 0x00, 0x00, 0x00};
void FLASH::ReadJEDECV2()
{
lpspi3.ReadFlashV2(JEDECV2, 4); //pass JEDEC command + 3 dummy bytes
}
void HardwareSPI::ReadFlashV2(const uint8_t* data, uint32_t len)
{
for (uint8_t i = 0; i < len; ++i)
{
if (i == len - 1)
{
base->TCR &= ~LPSPI_TCR_CONT_MASK; // Clear CONT for the last byte
}
else
{
base->TCR |= LPSPI_TCR_CONT_MASK; // Set CONT for continuous transfer
}
LPSPI_WriteData(base, data[i]); // Write data to the transmit data register (TDR)
while (LPSPI_GetTxFifoCount(base) > 0) {}
while (LPSPI_GetRxFifoCount(base) == 0) {}
LPSPI_ReadData(base); // Read the received data from the receive data register (RDR)
}
}
