AnsweredAssumed Answered

Is EOQF unreliable on PK60N512

Question asked by Ciaran Mac Aonghusa on Sep 11, 2013
Latest reply on Sep 26, 2013 by EARL GOODRICH

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;

}

Outcomes