SPI finished indication in master mode

Hi,

I'm trying to use SPI0 on the ADSP-21569 in master mode to configure an external chip.

Simplified code:

#define SPI0_SLVSEL          (ENUM_SPI_SLVSEL_SSEL1_HI | ENUM_SPI_SLVSEL_SSEL1_EN);

#define SPI0_TX_ENABLE  (ENUM_SPI_TXCTL_TX_EN | ENUM_SPI_TXCTL_TTI_EN)

#define SPI0_CTL                (ENUM_SPI_CTL_EN | ENUM_SPI_CTL_MASTER | ENUM_SPI_CTL_SIZE08 | ENUM_SPI_CTL_HW_SSEL)

#define EXT_CMD_RESET (0xFF)

.... //init SLVSEL, TXCTL, CTL

ustat1 = EXT_CMD_RESET;
dm(REG_SPI0_TFIFO) = ustat1;

The data is transmitted correctly and the chip select works also as expected with ASSEL=1;

But I do not get an information when the SPI transfer is really finished.

I'm not talking about empty TX FIFO flag etc and I do not want to use DMAs and IRQs for this.

I just need the information when the transfer was done on the pins and the SPI controller has released the CS (SPI0_SEL1) to high.

In older SHARCs I've used the SPIF flag in the status register but none of the status register bits is changing with this operation.

Regards

Christian



Changed typo
[edited by: ChristianH at 5:34 AM (GMT -4) on 16 Aug 2021]
  • +1
    •  Analog Employees 
    on Aug 20, 2021 6:14 AM

    Hi,

    The SPI_STAT.SPIF bit indicates that a single word transfer is complete. Please note that the SPIF(SPI Finished) bit would be set in the beginning, it gets cleared during the single word transfer and again it gets set after the single transfer finish.

    In order to test this scenario, you can poll the SPIF to become zero in the SPI Transmit Interrupt Handler (ISR) as per the below code snippet.

    void SPI0_TxDMA_Handler (uint32_t iid, void *handlerArg)
    {
    static int i;
    for(i=0; i<=BUFF_SIZE; i++)
    {
    *pREG_SPI0_TFIFO = SPI0_TxBUFF[i];

    while((*pREG_SPI0_STAT & BITM_SPI_STAT_SPIF)!=0);
    {
    count++;
    }
    }
    }

    The count value gives you the number of words transmitted. In order to understand that the SPIF bit is only cleared during transfer, you would put a breakpoint in the "while((*pREG_SPI0_STAT & BITM_SPI_STAT_SPIF)!=0);" condition. When you step through the code you cannot see that the execution never jumps to 'count++' instruction.
    This happens because the SPIF bit cleared during the transfer and soon after the transfer it becomes set. By the time when processor hits on the breakpoint and step through further execution, the SPIF bit might have changed from 1-->0-->1. Then if you check the 'while' condition if would become true ("while(1);") and it loops there itself. In case if you don't put a breakpoint and run as it is, the condition will be executed ("while(0);") and the count will be incremented.

    I would suggest you poll the SPI_STAT.TF (Transmit Finish Indication) bit in the SPI transmit ISR which indicates that the SPI has detected the finish of a transmit burst transfer (the SPI_TWC count decrements to zero). This condition can only occur when SPI_TXCTL.TTI and SPI_TXCTL.TWCEN are enabled.

    The SPI_TXCTL.TTI bit enables initiation of transmit transfers if the transmit FIFO (SPI_TFIFO) is not empty. The bit also enables this initiation if SPI_TWC is not zero when SPI_TXCTL.TWCEN is enabled. Enabling SPI_TXCTL.TTI prevents transmit underrun errors from occurring. As soon as the SPI_TWC (Transmitted Word Count Register) becomes zero, the SPI_STAT.TF bit changes to 1 which indicate that the transfer is completed.

    Regards,
    Anand Selvaraj.

  • Hi,

    I use the SPI_STAT.TF solution now and it works.

    Thank you!

    Regards

    Christian