Hi,
I am trying to use a simple polled Tx driver for SPI on the PK60N512 (2N30D). For my app I need to manually control a CS for specific time. My micro is master - so in order to control the CS after the last xfer I need to wait on EOQF. Sometimes it works, sometimes not. Code below. See comment where it gets stuck near the bottom of spi_write waiting for EOQF.
Thank you,
Ciarán
void spi_init(spi_id_t spi_id)
{
spi_regs[spi_id]->MCR = SPI_MCR_HALT_MASK; // Ensure halt (Only safe to write other MCR bits when Halted)
spi_regs[spi_id]->MCR &= ~SPI_MCR_MDIS_MASK; // Must be zero in order for TFFF to work properly
// Master mode, flush fifos, disable fifos (i.e sz = 1), non contiuous clk mode,
spi_regs[spi_id]->MCR |= SPI_MCR_MSTR_MASK | SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK| SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK ;
// CTAR determines frame size=FMSZ=1 (set here for 16), clock divider, and CPHA=1,
spi_regs[spi_id]->CTAR[0] = SPI_CTAR_FMSZ(15) | SPI_CTAR_BR(0xE) |SPI_CTAR_CPHA_MASK;
// Start Peripheral
spi_regs[spi_id]->MCR &= ~SPI_MCR_HALT_MASK; // CMA_DBG - maybe need on off per usage
}
void spi_write(spi_id_t spi_id, uint8_t* data, uint16_t len)
{
uint32_t tx_word;
// Loop over data and pad data so that it's 16 bit aligned
while (len)
{
// Wait TFFF (Tx FIFO Fill Flag)
// See important note on TFFF section 49.4.7.2 of the datasheet
while (!(spi_regs[spi_id]->SR & SPI_SR_TFFF_MASK));
// Use long winded way to enfore 16 bit tx. (ie. two bytes and mark pad bytes as recognisable for debug
if (len > 1)
{
tx_word = (*data << 8) + *(data+1);
data += 2;
len -= 2;
}
else
{
tx_word = (*data << 8) + 0xAA; // padding
len = 0;
}
// PUSHR - write data : CONTinuous CS, using CTAR0, and mark last transfer so we get an EOQ Flag below
if (!len)
{
tx_word |= (SPI_PUSHR_EOQ_MASK | SPI_PUSHR_PCS(1));
}
else
{
tx_word |= (SPI_PUSHR_PCS(1));
}
spi_regs[spi_id]->PUSHR = tx_word;
// Clear TFFF
spi_regs[spi_id]->SR |= SPI_SR_TFFF_MASK;
}
// Wait on last transfer to complete (we are implementing a synchronous write function)
while (!(spi_regs[spi_id]->SR & SPI_SR_EOQF_MASK)); <----- sometimes gets stuck here, why? /////////////////
spi_regs[spi_id]->SR |= SPI_SR_EOQF_MASK;
}