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.

MSPM0G1106: SPI Read and Write

Part Number: MSPM0G1106
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Hello,

I want to do SPI read and write with Texas MSPM0G1106 IC.

First of all, I have done SPI read and write with another MCU before. Here is the codes.

unsigned char MFRC522_SPIreceive(unsigned char address_rcv)
	{
		SPI_receive_address= (((address_rcv<<1)&0x7E) | 0x80);
		
  	SPI_NSS= 0;
    
		SPI_WRITE_TX(SPI0, SPI_receive_address);
		while(SPI_IS_BUSY(SPI0));
	
    SPI_ClearRxFIFO(SPI0);
	
		SPI_WRITE_TX(SPI0, DUMMY);
		while(SPI_IS_BUSY(SPI0));
  	
		SPI_Received_data = SPI_READ_RX(SPI0);
  		
		SPI_NSS= 1; 
	
		return SPI_Received_data;
	}

When I look at the debug of MCU, I can see the values I want. But when I look at the debug of Texas, I read 0xFF. Normally I should read 0x3F.

Logic Analyzer

(In the picture below you can see the image taken from Logic Analayzer).

SPI Init

SPI Init

SPI Settings 2 

SPI Settings

SPI Settings

SPI Settings

SYSCONFIG_WEAK void SYSCFG_DL_SPI_0_init(void)
{
    DL_SPI_setClockConfig(SPI_0_INST, (DL_SPI_ClockConfig *) &gSPI_0_clockConfig);

    DL_SPI_init(SPI_0_INST, (DL_SPI_Config *) &gSPI_0_config);

    /* Configure Controller mode */
    /*
     * Set the bit rate clock divider to generate the serial output clock
     *     outputBitRate = (spiInputClock) / ((1 + SCR) * 2)
     *     400000 = (16000000)/((1 + 19) * 2)
     */
    DL_SPI_setBitRateSerialClockDivider(SPI_0_INST, 19);
    /* Set RX and TX FIFO threshold levels */
    DL_SPI_setFIFOThreshold(SPI_0_INST, DL_SPI_RX_FIFO_LEVEL_1_2_FULL, DL_SPI_TX_FIFO_LEVEL_1_2_EMPTY);

    /* Enable module */
    DL_SPI_enable(SPI_0_INST);
}

SPI Init Code

IC Pins

IC Pins

Config etc. settings are as in the pictures.

The code I use is as follows.

unsigned char MFRC522_SPIreceive(uint8_t address_rcv)
{
    uint8_t SPI_receive_address = (((address_rcv << 1) & 0x7E) | 0x80);

    //MFRC_NSS_OFF;

    DL_SPI_transmitData8(SPI_0_INST, SPI_receive_address);
    delay_cycles(500);
    while (DL_SPI_isBusy(SPI_0_INST));

    DL_SPI_transmitData8(SPI_0_INST, DUMMY);
    delay_cycles(500);
    while (DL_SPI_isBusy(SPI_0_INST));

    SPI_Received_data= DL_SPI_receiveData8(SPI_0_INST);

    //MFRC_NSS_ON;


    return SPI_Received_data;
}

Main code

MFRC522_SPIreceive(0x11);
delay_cycles(500);

Do I have a mistake in the reading code? If so, how can I fix it?

Thank you in advanced.

  • Your previous code has

    >  SPI_ClearRxFIFO(SPI0);

    to clear out the Rx byte you got back from sending the command. I don't see an exact equivalent, but since you know there's only one byte in the Rx FIFO you could use:

    > (void)DL_SPI_receiveData8(SPI_0_INST); // Read and throw away

  • (void)DL_SPI_receiveData8(SPI_0_INST); // Read and throw I am trying to use this code, but there is no data retrieval, what code should I write?

  • Try to add :

    while (DL_SPI_isRXFIFOEmpty(spi));

    before SPI_Received_data= DL_SPI_receiveData8(SPI_0_INST);

  • uint8_t DUMMY=0x00;
    
    
    unsigned char MFRC522_SPIreceive(uint8_t address_rcv)
    {
    
        uint8_t SPI_receive_address = (((address_rcv << 1) & 0x7E) | 0x80);
    
       
    
        DL_SPI_transmitData8(SPI_0_INST, SPI_receive_address);
    
        while (DL_SPI_isBusy(SPI_0_INST));
    
        while (DL_SPI_isRXFIFOEmpty(SPI_0_INST));
    
    
    
    
        DL_SPI_transmitData8(SPI_0_INST, DUMMY);
    
        while (DL_SPI_isBusy(SPI_0_INST));
    
        SPI_Received_data= DL_SPI_receiveData8(SPI_0_INST);
    
    
    
    
        return SPI_Received_data;
    }
    
    
    
    
    
    
    int main(void)
    {
        SYSCFG_DL_init();
    
        while (1) {
    
           MFRC522_SPIreceive(0x11);
            delay_cycles(500000);
    
        }
    }

    I can see 0x3f in other MCU, but I can't see it in Texas, it doesn't appear in the debug.

  • I'm not sure I understand what you mean by "no data retrieval".

    That line should be inserted just before the second call to DL_SPI_transmitData8 (just as it was in your original code).

    In the SPI, every Tx byte gets back an Rx byte. Even if you're not interested in the Rx byte, you need to deal with it, usually by reading it and throwing it away.

  • I don't understand why I don't have it. I'm constantly reading 0xff from the buffer. I checked my hardware. Did I do the SPI configuration wrong? Could you check it?

  • If you're getting back 0xFF rather than the 0x00 shown in your analyzer trace, I suppose that means you have leftover bytes in the (Rx) FIFO from some earlier transactions. If so, you should do a full empty of the FIFO with something like:

    while (!DL_SPI_isRXFIFOEmpty(SPI_0_INST)) {(void)DL_SPI_receiveData8(SPI_0_INST);} // Empty the Rx FIFO

  • The value I need to read from FIFO is 0x3f, but I always read 0xff. I will implement what you said tomorrow and let you know the situation.

  • We are reading, but we need to read the mathematical process as follows. Why might it be?

    uint8_t SPI_receive_address = (((address_rcv << 1) & 0x7E) | 0x80);
    
    
    
        DL_SPI_transmitData8(SPI_0_INST, SPI_receive_address);
    
        while (DL_SPI_isBusy(SPI_0_INST));
    
    
        while (DL_SPI_isRXFIFOEmpty(SPI_0_INST));
    
        DL_SPI_transmitData8(SPI_0_INST, DUMMY);
    
        while (DL_SPI_isBusy(SPI_0_INST));
    
    
    
        while (!DL_SPI_isRXFIFOEmpty(SPI_0_INST)) {
            SPI_Received_data= DL_SPI_receiveData8(SPI_0_INST);
    }
        SPI_Received_data=0xff-SPI_Received_data;<-------------

  • That wasn't exactly what I was suggesting, but it seems that it should work.

    It almost sounds like you've somehow set "invert" in your Iomux configuration. In sysconfig, what does it show under "Communications->SPI->Pin Configuration->SPI POCI [Enable pin configuration checkbox]->Digital IOMUX Features->Invert"?

  • Hello, I think we have come a long way, but I am telling you my problem right away because it is not working exactly as desired. I solved the problem of reading data correctly, but some of the data I read in the FIFO is old data. Let me explain it like this: The field I read in the attachment I sent is not the same as the field I read in the debug. I think it's a data read slip, I can't be sure that the FIFO is emptied and I can't empty it manually. By the way TxControlReg= 0x14 . Do you have new recomandation ?

      ...

    unsigned char MFRC522_SPIreceive(unsigned char address_rcv)
    {
        // Okuma işlemi için adres
        uint8_t SPI_receive_address = (((address_rcv << 1) & 0x7E) | 0x80);
    
        MFRC_NSS_OFF;
    
    
        DL_SPI_transmitData8(SPI_0_INST, SPI_receive_address);
    
        while (DL_SPI_isBusy(SPI_0_INST));
    
    
        //while (!DL_SPI_isRXFIFOEmpty(SPI_0_INST));
    
        DL_SPI_transmitData8(SPI_0_INST, DUMMY);
        while (DL_SPI_isBusy(SPI_0_INST));
    
    
        while (!DL_SPI_isRXFIFOEmpty(SPI_0_INST)) {
        SPI_Received_data= DL_SPI_receiveData8(SPI_0_INST);
    }
        //SPI_Received_data=0xff-SPI_Received_data;
    
    
    MFRC_NSS_ON;
    
    
    delay_cycles(200);
    
    
    
        return SPI_Received_data;
    }

  • You can read SPI data to empty fifo

  • unsigned char MFRC522_SPIreceive(unsigned char address_rcv)
    {
        // Okuma işlemi için adres
        uint8_t SPI_receive_address = (((address_rcv << 1) & 0x7E) | 0x80);
    
        // NSS'i düşürün, böylece SPI ile haberleşme başlayacak
        MFRC_NSS_OFF;
    
        // Adresi gönderin
        DL_SPI_transmitData8(SPI_0_INST, SPI_receive_address);
    
        // SPI işlemi bitene kadar bekleyin
        while (DL_SPI_isBusy(SPI_0_INST));
    
        // RX FIFO'nun boş olup olmadığını kontrol edin ve boş olduğundan emin olun
        while (!DL_SPI_isRXFIFOEmpty(SPI_0_INST)) {
            // Eğer FIFO'da veri varsa eski veriyi temizleyin
            DL_SPI_receiveDataBlocking8(SPI_0_INST);
        }
    
        // Veri gönderin, dummy data kullanarak (saat sinyali üretmek için)
        DL_SPI_transmitData8(SPI_0_INST, DUMMY);
    
        // SPI işlemi bitene kadar bekleyin
        while (DL_SPI_isBusy(SPI_0_INST));
    
        // RX FIFO'nun dolu olup olmadığını kontrol edin ve veri al
        while (DL_SPI_isRXFIFOEmpty(SPI_0_INST));  // FIFO dolana kadar bekleyin
    
        SPI_Received_data = DL_SPI_receiveDataBlocking8(SPI_0_INST);
    
        // SPI işlemi tamamlandıktan sonra NSS'i tekrar yükseltin
        MFRC_NSS_ON;
    
        // Gerekli gecikme
        delay_cycles(200);
    
        // Alınan veriyi döndürün
        return SPI_Received_data;
    }
    

    Hello, I think I solved my problem. The data I read is the data that was previously read and written to the fifo. As soon as I send the address, I make an empty reading and throw it away and read the real data.

  • I'm glad you got it working.