This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Possible timing problem (UART/SPI/instructions) in F28069 controlSTICK

Hi Guys, working on a new TIDA and playing with controlSTICK I ran into a strange problem. I am sending out 4B data over SPI (master) and for that reason I created following function which works....

/* PUSH data to SPI buffer - left adjusted */
#define SPIA_PUSH(TX) SpiaRegs.SPITXBUF = (TX << 8)
/* POP data from SPI buffer - right adjusted */
#define SPIA_POP SpiaRegs.SPIRXBUF

Uint32 hal_Xmit4BSPI(Uint32 frame)

{
    Uint32 rxval = 0x00000000; /* incomming data */
    /* empty RX and TX 4B FIFOs */
    SpiaRegs.SPIFFTX.bit.TXFIFO = 0; /* reset FIFOs */
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0;
    asm(" NOP"); /* probably not needed */
    asm(" NOP"); /* probably not needed */
    SpiaRegs.SPIFFTX.bit.TXFIFO = 1;
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1; /* release from reset */

    /* quick & dirty ! */
    SPIA_PUSH(frame>>24); /* first byte (from most significant) */
    SPIA_PUSH(frame>>16);
    SPIA_PUSH(frame>>8);  
    SPIA_PUSH(frame); /* last byte */
    /* wait until the transmition is finished */ 
    while(SpiaRegs.SPISTS.bit.INT_FLAG == 0){EMPTY_LOOP};
 // asm(" NOP"); /* probably not needed */
 // asm(" NOP"); /* probably not needed */
    /* get data from RX FIFO */
    rxval = SPIA_POP; /* first byte (from most significant) */
    rxval <<= 8;
    rxval |= SPIA_POP;
    rxval <<= 8;
    rxval |= SPIA_POP;
    rxval <<= 8;
    rxval |= SPIA_POP;

    /* NCS must remain high at least 200ns */
    HAL_DELAY_US(1);
    return(rxval);
}

And I call my function temporary from my main loop which looks like this:

int main(void)
{
    hal_InitSysCtrl(); /* inits clock domains, PLL */
    hal_InitGPIO(); /* practically default config + LED */
    hal_InitUART(); /* inits UART 115200 8N1 */
    xdev_out(hal_PutcUART); /* inits xprintf function */
    pga411_Init(); /* inits PGA411 driver */

    /* endless loop */
    while (1)
    {
        hal_ToggleLED();
        HAL_DELAY_US(500000);
        xprintf("Hello UART \r");
        asm(" NOP"); /* probably not needed */ 
        hal_Xmit4BSPI(0x12345678);
}

        #pragma diag_suppress 112 /* to get rid of warning that code is unreachable */

        return 0;
        #pragma diag_default 112 /* restore error level */
}

Problem description:

I found out that I need to have purple or yellow assembly to have the code running properly.  Otherwise the first hal_Xmit4BSPI call passes properly BUT later calls will end in program never leaving the while condition (INT_FLAG never set).

I could understand that the yellow ASM lines may help some internal synchronization but solving the problem with a NOP even before the function call is strange. xprintf is just an UART output.

CPU is running at 80 MHz from the internal A oscillator and PLL, LowSpeed clock is also 80 MHz. SPI clock is 8 MHz. 

I am not asking for help but if you were interested in further data and whole CCS project we may get in touch via webex or internal mail.

Cheers,

Jiri, Freising.

  • Jiri,

    This is very interesting and at the moment I don't think I have a good explanation of what is happening.

    I know you have said this is working fine, but I would like to  know if you were to remove the nops and change your polling loop to be:

    while(SpiaRegs.SPIFFRX.bit.RXFFST < 4); 
    or
    while(SpiaRegs.SPIFFTX.bit.TXFFST != 0);

    would the function work?

    I will contact you offline and we can see if we can explain what is exactly happening, the post our findings on here.

    Regards,
    Mark

  • I am just closing the loop here:

    When using the FIFO, the SPI_INT flag will be cleared by the hardware when the data is moved from SPIRXBUF to the FIFO.

    The suggested resolution is to NOT use the SPI_INT flag while FIFO mode is enabled. To verify that a word has been transmitted completely, polling RXFFST field until there is a change, indicating that a new word has been fully received.

    Regards,
    Mark
  • Hi Mark, 

    thank you for helping me with this. I can confirm that 

    while(SpiaRegs.SPIFFRX.bit.RXFFST < 4){EMPTY_LOOP};

    works well. The system now waits until the SPI communications is finished.

    Best Regards, Jiri