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.

RM48 - spiTransmitData from spi.c

Other Parts Discussed in Thread: HALCOGEN

Device used: RM48L952ZWT

Hello,

I try to use spiTransmitData, function generated by Halcogen. I see at the end of the function a check done on Rx flag (= 1 means buffer full)

 while((spi->FLG & 0x00000100U) != 0x00000100U)
        {
        } /* Wait */

Should it not be that:

 while((spi->FLG & 0x00000200U) != 0x00000200U)
        {
        } /* Wait */

Meaning that Tx buffer is empty??

Have a good day

  • Hi user4544371,

    The reason is that the TX Ready flag is set as soon as the transfer starts.. the SPI is double buffered.
    But the function is written to block until the transmission ends, and it reads the SPI buf after the transmission to
    avoid having the overrun error flag set.

    That's why it's checking for the receive flag instead of the transmit at the end. the next line reads the receive data
    to avoid overflow

    while((spi->FLG & 0x00000100U) != 0x00000100U)
    {
    } /* Wait */
    SpiBuf = spi->BUF; <<< cannot do this, until receive data is ready.

    -Anthony
  • Hello Anthony,

    First thanks for this reply!

    Regarding while loop, does it mean that I have to use SPI in a special way (like programming slave to send back ack or something like that)? My program is systematically blocked in this loop because no data received...

    Regarding spiBuf, this variable is local and linked to...nothing... I conclude that it is useless.

    Below is the code from spi.c:

    uint32 spiTransmitData(spiBASE_t *spi, spiDAT1_t *dataconfig_t, uint32 blocksize, uint16 * srcbuff)
    {
    volatile uint32 SpiBuf;
    uint16 Tx_Data;
    uint32 Chip_Select_Hold = (dataconfig_t->CS_HOLD) ? 0x10000000U : 0U;
    uint32 WDelay = (dataconfig_t->WDEL) ? 0x04000000U : 0U;
    SPIDATAFMT_t DataFormat = dataconfig_t->DFSEL;
    uint8 ChipSelect = dataconfig_t->CSNR;

    /* USER CODE BEGIN (10) */
    /* USER CODE END */

    while(blocksize != 0U)
    {
    if((spi->FLG & 0x000000FFU) !=0U)
    {
    break;
    }

    if(blocksize == 1U)
    {
    Chip_Select_Hold = 0U;
    }
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
    Tx_Data = *srcbuff;

    spi->DAT1 = ((uint32)DataFormat << 24U) |
    ((uint32)ChipSelect << 16U) |
    (WDelay) |
    (Chip_Select_Hold) |
    (uint32)Tx_Data;

    /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
    srcbuff++;

    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
    while((spi->FLG & 0x00000100U) != 0x00000100U)
    {
    } /* Wait */

    SpiBuf = spi->BUF;

    blocksize--;
    }

    /* USER CODE BEGIN (11) */
    /* USER CODE END */

    return (spi->FLG & 0xFFU);
    }

    Many thanks for your help!

    Frederic
  • Frederic,

    user4544371 said:
    Regarding while loop, does it mean that I have to use SPI in a special way (like programming slave to send back ack or something like that)? My program is systematically blocked in this loop because no data received...

    There isn't any sort of ACK and you don't even need to have a slave send anything back for this example.

    user4544371 said:
    Regarding spiBuf, this variable is local and linked to...nothing... I conclude that it is useless.

    The data is discarded in this function - yes - because it is a transmit only function.

    But the SPI always transmits and receives at the same time.  

    The act of reading spi->BUF clears the RX full status - preventing an overrun error from occurring if you call the transmit function again.

    Try commenting out the read of spi->BUF and you'll see that after a few calls to spiTransmitData- you will have the receive overrun error flag set.

  • Hello Anthony,

    Ok, issue solved...

    I first configured SOMI as normal IO because not used in my design... So the SPI block did not detect message reception in parallel with emission.

    In parallel, please note that HalcoGen bugs on SPI1SOMI[0] configuration... Here are all the details I can give:

    Halcogen 04.05.02

    Issue: In MIBSPI1 - MIBSPI1Port - SOMI[0] Pin mode setting => A configuration on this pin seems to have no effect on spiREG1->PC0.

     spiREG1->PC0  =   (uint32)((uint32)1U << 0U)  /* SCS[0] */
                        | (uint32)((uint32)1U << 1U)  /* SCS[1] */
                        | (uint32)((uint32)1U << 2U)  /* SCS[2] */
                        | (uint32)((uint32)0U << 3U)  /* SCS[3] */
                        | (uint32)((uint32)0U << 4U)  /* SCS[4] */
                        | (uint32)((uint32)0U << 5U)  /* SCS[5] */
                        | (uint32)((uint32)0U << 8U)  /* ENA */
                        | (uint32)((uint32)1U << 9U)  /* CLK */
                        | (uint32)((uint32)1U << 10U)  /* SIMO[0] */
                        | (uint32)((uint32)0U << 11U)  /* SOMI[0] */
                        | (uint32)((uint32)0U << 17U)  /* SIMO[1] */
                        | (uint32)((uint32)0U << 25U); /* SOMI[1] */

    The line /*SOMI[0] */ never goes to 1 so SOMI[0] is not activated...

    Setting manually this bit to 1 solve my issue.

    Thanks Anthony for your help