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.

MSPM0G3507-Q1: The SPI communication cannot read the RXDATA register

Part Number: MSPM0G3507-Q1
Other Parts Discussed in Thread: ADS8688, MSPM0G3507

Tool/software:

I am currently using the SPI function of the MSPM0G3507-Q1 chip; The following is my function introduction, I set MSPM0G3507-Q1 as the host, set ADS8688 as the slave, the host sends the command code (0x00000000,0xA0000000), the data is collected from the slave machine and returned to the host. This is the process I expected, but during use, I could not receive the data returned by the machine (to be precise, I set the receive interrupt in the program, and added the breakpoint verification in the interrupt, entering the interrupt is normal, but I can not read the data in the RxData register, I detected the status of RXFIFO, I can not read the data in the RXdata register. It appears as non-empty). I used oscilloscope PICO, POCI, CLK, CS pins in the slave machine to display whether the waveform was correct. What are the reasons for this? How to deal with it?
Below is part of my program code and oscilloscope picture

//Initial configuration of SPI
void SPI0_INIT()
{
    //设置时钟源和分频
    mySPI0->CLKSEL.bit.SYSCLK_SEL=1;
    mySPI0->CLKDIV.bit.RATIO=0;

    mySPI0->CTL0.bit.CSSEL=1;    //CS线的选择
    mySPI0->CTL0.bit.DSS=0xF;    //数据尺寸
    mySPI0->CTL0.bit.SPH=1;      //极性相位
    mySPI0->CTL0.bit.SPO=0;
    mySPI0->CTL0.bit.FRF=1;      //传输帧格式,
    mySPI0->CTL1.bit.PES=0;      //偶数奇偶校验模式
    mySPI0->CTL1.bit.CP=1;       //控制器或外设模式选择
    mySPI0->CTL1.bit.PTEN=0;     //发送奇偶校验
    mySPI0->CTL1.bit.PREN=0;     //接收奇偶校验
    mySPI0->CTL1.bit.MSB=1;      //传输的开始端,高位优先

    //串行时钟分频器:用于产生SPI的发送和接收比特率
    mySPI0->CLKCTL.bit.SCR=0xE;

    //设置RX和TX FIFO中断阈值级别
    mySPI0->IFLS.bit.RXIFLSEL=0x2;
    mySPI0->IFLS.bit.TXIFLSEL=0x2;

    //使能接收中断
    //mySPI0->C_IMASK.reg=0xFF;
    //mySPI0->C_IMASK.bit.TXEMPTY=1;
    mySPI0->C_IMASK.bit.IDLE=1;
    mySPI0->C_IMASK.bit.RX=1;
    //mySPI0->C_IMASK.bit.RXFULL=1;
    //mySPI0->C_IMASK.bit.DMA_DONE_RX=1;

    //使能
    mySPI0->CTL1.bit.ENABLE=1;
}


//Interrupt part
switch (mySPI0->C_IIDX.bit.STAT)
    {
        case 0x4:                                    //接收中断
        {
            ALLFC.P01.FC[10]++;//mySPI0->C_IMASK.reg;
            SPI.RxCount--;
            SPI.RxDataW[SPI.RxCount]=mySPI0->RXDATA;
            if(SPI.RxCount==0)
            {
                ALLFC.P01.FC[11]++;
                SPI.TimeOut=0;
                SPI_RX();
            }
            break;
        }
        
        
        
//Sending part
void    SPI_TX32(Uint32 _Data)              //SPI发送函数
{
    if(SPI.Busy) return;
    SPI.TxD32=_Data;
    SPI.TxCount=2;
    SPI.RxCount=2;

    mySPI0->TXDATA = SPI.TxDataW[1];
    mySPI0->TXDATA = SPI.TxDataW[0];
    SPI.Busy=5;
}

  • the host sends the command code (0x00000000,0xA0000000)

    This is more reasonal.

    I wondered in previous post why the data sent was all 0, that's because this command.

    First step, please go through these introduction first:

        https://blog.csdn.net/Naisu_kun/article/details/118102844

        https://blog.csdn.net/as480133937/article/details/105764119

        SPI is a Full-duplex communication bus, this means that when you send data, invalid data will be received.

    The second step, please go through the ADS configuration steps.

        Make sure that I have already config the ADS device correctly, then you can start ADS conversion by sending  command to it.

        You can get the instruction here of ADS device: https://www.ti.com/lit/ds/symlink/ads8688.pdf

        8.4.1.1 Digital Pin Description

        And 8.4.1.2 Data Acquisition Example is the SPI communication sequence that we need to control ADS device.

        You need to control MSPM0's SPI follow the steps in 8.4.1.2 Data Acquisition Example.

    Region 1 is used to send commands to the ADS, and you also receive some useless data from Rx.

    Also, in region 2, to read data from the ADS, you need to send some useless data such 0xFF or 0x00 to enable SCK, so that the clock is active so that the ADS has a chance to send data back.

  • Mark: Here is another E2E thread that contain some useful Scope figure of this command.

    I set MSPM0G3507-Q1 as the host, set ADS8688 as the slave, the host sends the command code (0x00000000,0xA0000000)

    e2e.ti.com/.../mspm0g3507-q1-the-spi-communication-cannot-read-the-rxdata-register

  • My current situation is that the slave can send data, in another post, the POCI pin waveform of the oscilloscope proves this (and the data is correct), I can now trigger the SPI receive interrupt, but the data cannot be read in the RXDATA register

  • Region 1 is used to send commands to the ADS, and you also receive some useless data from Rx.

    Do you clear the useless data mentioned in region 1?

    Another from my side, how many bytes do you send to ADS via SPI?

            Since command is 0x00000000,0xA0000000, at least you need to send 8 byte for command.

            And you want to read back 2*32bit from ADS right?

  • 1: What do you mean by this useless data? (For the ADS8688, the function code 0x00000000 has been explained in the technical manual, how is it useless data?)

    2: I sent a 32-bit data to the ADS via SPI (I did not enable PACKEN), I want to read 2*16 bits from the ADS

  • 1: What do you mean by this useless data? (For the ADS8688, the function code 0x00000000 has been explained in the technical manual, how is it useless data?)

    Invalid data, or useless data, this part of data is useless, data that has no effect.

    2: I sent a 32-bit data to the ADS via SPI (I did not enable PACKEN), I want to read 2*16 bits from the ADS

    Can you show me the software step?

    So, on hardware, from send to receive finished, you totally send 32bit data only?

  • Software steps: I set the timer event to send data every 1ms (send function of the above code), and also set the SPI receiving interrupt to receive data (receive interrupt of the above code). After receiving the data, it is stored in the SPi.rxdataw array. In the loop of the main function, the SPI.rxdataw array is processed. This is a complete process

  • Software steps: I set the timer event to send data every 1ms (send function of the above code), and also set the SPI receiving interrupt to receive data (receive interrupt of the above code). After receiving the data, it is stored in the SPi.rxdataw array. In the loop of the main function, the SPI.rxdataw array is processed. This is a complete process

    Seems you only send 32bit command, but if you need to read back something, you need to send more to enable clock.

    I sent a 32-bit data to the ADS via SPI (I did not enable PACKEN), I want to read 2*16 bits from the ADS

    This requirement need you to send a 32bit to send command, and send another 2*16 bit 0x00 or 0xFF from M0 to ADS to enable clock, to read back data.

    Full-duplex communication bus

    Please go through these content.

  • According to the oscilloscope waveform image collected in another post, my sending process is to send 0xA0000000 once, and then send 0x00000000 eight times. The logic flow of SPI communication code is verified on another type of chip, and then ported to MSPM0G3507. When my RXFIFO check, the display is not empty, but also can trigger an interrupt, indicating that the data has come back, this inference is no problem. But it can't be read in RXDATA register, now that's the problem

  • Please try to set a large rx buffer.

    From send 0xA0000000 to 8 times 0x00000000 finished, there will be 36 bytes Rx data from SPI.

    Please check these Rx data.

  • 1:I set the FIFO threshold to 1/2, store 2 16-bit entries,

    2:My current problem is that I can't receive the data of RXDATA register in the software side, and I can only view it on the oscilloscope. This is exactly the problem I came to this forum to solve, how can I have data in RXDATA (RXFIFO is not empty state)

  • For the current situation, I will recommend you to try SPI demo code from MSPM0 SDK, following the readme file instruction.

    To setup a test environment that can successfully run SPI read/write test.

    Then, we can try to move to your customer code and customer PCB board step by step.

    I have go through your SPI source code, it's seems OK.

    Also, you can send me your CCS project through Ti's FAE, I can help to review, but this may takes few days.

    1:I set the FIFO threshold to 1/2, store 2 16-bit entries,

    This will only receive the region 1's useless data. The data received while sending the command 0xA0000000.

    But I still don't know how to control ADS, this is depending on ADS's datasheet, such as

    how many bytes need to send to ADS as command, how many bytes I need to receive from ADS.

    But from this figure above:

    command seems to be 16bit and received data is depending on ADS device number.

    From send to read finishing, the valib data should be 17th to 32nd bit.

  • How do I send the CCS project to you

  • I received your project, need to takes a few days to review.

  • You SPI.RxCount need to set tx_count + rx_count.

    There will be valid data at SPI.RxCount[tx_count].

    For mySPI0->TXDATA it's a max 16-bit wide register, you can not write a 32 bit to it.

    Please refer to MSPM0 SDK demo code for SPI function handle:

    C:\ti\mspm0_sdk_2_04_00_06\examples\nortos\LP_MSPM0G3507\driverlib\spi_controller_multibyte_fifo_poll

  • 1:About this, is the value of SPI.RxCount set to the plus of tx_count + rx_count

    You SPI.RxCount need to set tx_count + rx_count.

    2:I know that mySPI0->TXDATA is a register of its bit width. When I send, I split a 32-bit data into 16 high bits and 16 low bits.

    For mySPI0->TXDATA it's a max 16-bit wide register, you can not write a 32 bit to it.

    3:On the third point, do you mean to use a For loop to read and receive data after the interrupt

    Please refer to MSPM0 SDK demo code for SPI function handle:

    C:\ti\mspm0_sdk_2_04_00_06\examples\nortos\LP_MSPM0G3507\driverlib\spi_controller_multibyte_fifo_pol

  • About this, is the value of SPI.RxCount set to the plus of tx_count + rx_count

    yes

    2:I know that mySPI0->TXDATA is a register of its bit width. When I send, I split a 32-bit data into 16 high bits and 16 low bits.

    Yes, Tx32 function is correct.

    On the third point, do you mean to use a For loop to read and receive data after the interrupt

    No, just a reference code for you, but I check your code again, SPI_TX32's send function is correct.

    Want you need to do is that you need to deal with region 1's data and send more data to TX depending on how many data you want to read back from ADS.

    That's why rx count and tx count need to follow below sequence:

    Also, for receive function, you also need call SPI_TX32 to receive the data.

    But you only call SPI_TX32(SpiTxData); once to send command, I didn;t find any other SPI send function.

    Here is the key point, SPI need to send something, to output SCLK, to let ADS have the clock signal to send ADC data back.

  • Want you need to do is that you need to deal with region 1's data and send more data to TX depending on how many data you want to read back from ADS.

    That's why rx count and tx count need to follow below sequence

    At this point, my slave currently has only one ADS8688 acquisition chip, and the oscilloscope picture I uploaded is equivalent to 0xA000 in region 1; In region 2 (from bit 17 to bit 32), 0x0000 is sent; I only need to read a piece of content from the slave;

    Also, for receive function, you also need call SPI_TX32 to receive the data.

    But you only call SPI_TX32(SpiTxData); once to send command, I didn;t find any other SPI send function.

    Here is the key point, SPI need to send something, to output SCLK, to let ADS have the clock signal to send ADC data back

    Receive function, need to continue to call SPI_TX32 function to handle?? What's the logic? I use this function to send, sure not to call ah. My send function is triggered by a timer of 1ms. As for what you said later about SPI having to send something to output SCLK, what I want to say is, please take a look at my oscilloscope waveform. My SCLK always has a waveform.

  • At this point, my slave currently has only one ADS8688 acquisition chip, and the oscilloscope picture I uploaded is equivalent to 0xA000 in region 1; In region 2 (from bit 17 to bit 32), 0x0000 is sent; I only need to read a piece of content from the slave;

    Yes, there will be some bytes received in region, these part is useless, you need to read them out from SPI rx (FIFO).

    Also, the next received data is valid.

    Receive function, need to continue to call SPI_TX32 function to handle?? What's the logic? I use this function to send, sure not to call ah. My send function is triggered by a timer of 1ms. As for what you said later about SPI having to send something to output SCLK, what I want to say is, please take a look at my oscilloscope waveform. My SCLK always has a waveform.

    emmmm, yes, there are SCK all time time. Time scale is 1ms, and you read ADS data every 1ms, correct?

    Receive function, need to continue to call SPI_TX32 function to handle?? What's the logic?

    Actually, yes, after send command, M0 need to send 0x00 to enabled SCLK.

    Since your scope capture time scale is 1 ms, I can not see the detailed information, could you please show me your single sequence of Tx - Rx wavefrom?

    Need to confirm the valid data come with which group of 16bits SCLK.

    My SCLK always has a waveform.

    Do you know which group Rx data is valid? How to confirm in software?

    From my point, you need to handle Rx data while send command.

    Also, you need to handle Tx data to enable SCLK when you want to receive the ADS data.

  • Yes, there will be some bytes received in region, these part is useless, you need to read them out from SPI rx (FIFO).

    Also, the next received data is valid.

    In SPI, FIFO is enabled by default and cannot be turned off. It can only set its threshold value, according to the data sheet, the user has no permission to operate the data in SPI, FIFO, no matter what reading method is based on the RXDATA register.

    emmmm, yes, there are SCK all time time. Time scale is 1ms, and you read ADS data every 1ms, correct?

    It is sent every 1ms, and the clock line appears every 1ms, but is only read effectively at the CS line low level

    Actually, yes, after send command, M0 need to send 0x00 to enabled SCLK.

    Since your scope capture time scale is 1 ms, I can not see the detailed information, could you please show me your single sequence of Tx - Rx wavefrom?

    Need to confirm the valid data come with which group of 16bits SCLK.

    The waveform data is shown below

    Do you know which group Rx data is valid? How to confirm in software?

    From my point, you need to handle Rx data while send command.

    Also, you need to handle Tx data to enable SCLK when you want to receive the ADS data

    I can't receive it in the software, which is my current problem. But according to the POCI and SCLK waveform, the last 16 bits are the data I want to receive, send command to process RX data, this part is what I said to send 0x00000000 all the time

  • I can't receive it in the software, which is my current problem. But according to the POCI and SCLK waveform, the last 16 bits are the data I want to receive, send command to process RX data, this part is what I said to send 0x00000000 all the time

    Yes, I also seen this.

    Since you send your command, then you need to read data from SPI FIFO.

    You will receive 2bytes after you send command, this part is region, useless, it's 0x0000.

    Then you need another two bytes to be received from SPI FIFO, this part is region 2, received data from ADS.

  • What is the next operation or processing? (Now it is known that when the MSPM0G3507 chip communicates with SPI, users cannot directly operate SPI-FIFO. There is no corresponding interface, and they can only operate the RXDATA register. For FIFO operations, only the status bit is used to detect whether there is data in it.)

  • RXDATA is the FIFO access interface.

    What is the next operation or processing?

    You will receive 2bytes after you send command, this part is region, useless, it's 0x0000.

    Then you need another two bytes to be received from SPI FIFO, this part is region 2, received data from ADS.

  • Can you be more specific about what I should do in the code, or what should I change in my existing code

  • How do I operate the rxdata register to read the data in the ADS collection area 2

    You will receive 2bytes after you send command, this part is region, useless, it's 0x0000.

    Then you need another two bytes to be received from SPI FIFO, this part is region 2, received data from ADS

  • How do I read the data in area 2

  • How do I read the data in area 2
    You SPI.RxCount need to set tx_count + rx_count.

    First tx_count length of rx data is from region 1, next rx_count length of rx data is from region 2, SDO.

  • Based on the amount of data I want to receive, my RxCount value is set to 4 according to your method, but my test array TEST_arr1 never has any data

  • I added the test point inside the 0x4 interrupt, entered the interrupt twice in 32 clock cycles, my SPI.RxDataW type is 16 bits (2 bytes), as expected, in SPI.RxDataW[1] is the data of region 1, in SPI.RxDataW[0] is the data of region 2, but the result is, The data content is always 0, which is inconsistent with the oscilloscope. According to your introduction, SPI.RxDataW[0] is the other 2 bytes you refer to, because the value of SPI.RxCount decreases by 1 with each interrupt.

  • This is strange, the data should be received and your interrupt has entered.

  • I added the test point inside the 0x4 interrupt, entered the interrupt twice in 32 clock cycles, my SPI.RxDataW type is 16 bits (2 bytes), as expected, in SPI.RxDataW[1] is the data of region 1, in SPI.RxDataW[0] is the data of region 2, but the result is, The data content is always 0, which is inconsistent with the oscilloscope. According to your introduction, SPI.RxDataW[0] is the other 2 bytes you refer to, because the value of SPI.RxCount decreases by 1 with each interrupt

    Yes, it's weird. The above problem description is a problem that I haven't solved so far, but neither the oscilloscope waveform nor the logic of the code are checking for errors. Receive interrupts are also triggered with the clock waveform. Please communicate with your engineering team to solve it as soon as possible. Before, I applied for your engineer to come to my site to solve the problem, but it was not successful

  • For this issue, please try to use a SPI demo in MSPM0 SDK, to setup a simple communication with ADS device.

    SPI demo in MSPM0 sdk is fully test.

    And another tips, is this SPI software test on other project or platform.

    Both two recommendation is used to confirm whether is a software issue.

    ---------------

    On hardware side, please confirm whether the signal line is connected.

    Or try to set the POCI to GPIO output and observe whether there is voltage toggle at the same test point.