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.

C2000 F28027 SPI Receive Strange Problem



Dear colleagues, 
I call for help with a strange situation with SPI connection. I want to connect a slave F28027 to a master ARM processor. The master works fine, it sends four 16 bit data and I can see the slave FIFO being populated accordingly trough debugging and, trough a logic analyzer, I can ensure the master sends correct data. However, the slave F28027 processor only reads 0xFFFF in each word transmitted. Even if I disconnect the MOSI pin, it still reads 0xFFFF regardless the situation. I have checked all the connections,  the SPISTE is connected to a GPIO in the master and the slave sends dummy data while receiving. I even tried replacing the slave processor, but the same occurs. 
I really appreciate some help here guys. Thank you. 

  • Any TI employee? It is a really weird problem. I already tried loopback to see if the SPI module works and it responds perfectly. The other processor is also fine. What am I missing here??? =((

  • Hi Filipe,

    Can you please clarify this? Are you saying that the RX FIFO on the slave is being correctly populated, but you can only read 0xFF out of it in your code?

    Filipe Taveiros said:
    I can see the slave FIFO being populated accordingly trough debugging and, trough a logic analyzer, I can ensure the master sends correct data. However, the slave F28027 processor only reads 0xFFFF in each word transmitted. 

    Please post your code as well as screenshots of your logic analyzer captures, if possible.

    Regards,

    Sam Friedman

  • Hi Sam, thank you for your answer.

    Yes, exactly. But, as I don't have access to the FIFO registers (only the FIFO status), I can tell only it receives the correct number of words, but I don't know if they are the correct words. I will try to explain step by step in the following figure (if the image is bad to read, see the PDF attached. 3010.Doc1.pdf):

    The processor is programmed as follows:

    1. The SPI module is configured as SLAVE, the FIFO is activated and the FIFO interrupt level is set to 4.
    2. The device sends periodically (1ms) four 16 bits words of dummy data, only if the FIFO is empty and the SPITXBUFF is also empty. Once the dummy frame is stored in the FIFO, it waits the master to start the transmission.
    3. A interrupt routine is called when the Receive FIFO reaches four words. The words are retrieved and stored in variables, and the dummy frame stored in the Transmit FIFO is shifted out.
    4. The Slave (F28027 processor) receives only 0xFFFF, and the Master reads also 0xFFFF.

    I think it is a SPI module error, but I can't affirm that. I have tried three different processors (F28027 Launchpad, all new in box), with the same result.

    Note: This is not the first error I found in the module. I have detected other (software correctable) issue with the SPI module, which works a little different that what is described in the SPI Reference Guide. If TI is interested to know, I will be happy to describe it.

  • Thank you for the detailed explanation. I have a few things I want you to explore.

    Have you connected a ground wire between the master and slave?

    What happens when you change the clock phase and polarity settings? Please try all four combinations to see if you get different results.

    Have you disabled the internal pullups on all of the SPI pins?

    Is it possible to get a scope or logic analyzer capture with all four of the SPI pins?

    Sam

  • Hi Sam, thank you very much for your help.

    Sam Friedman said:

    1. Have you connected a ground wire between the master and slave?

    2. What happens when you change the clock phase and polarity settings? Please try all four combinations to see if you get different results.

    3. Have you disabled the internal pullups on all of the SPI pins?

    4. Is it possible to get a scope or logic analyzer capture with all four of the SPI pins?

    Sam

    1. Yes, there is a ground wire.
    2. Yes, I have tried all combinations.
    3. No, I did not know about that. How do I do to disable? If there are pullups connected internally, it has a good chance to be the problem.
    4. Yes, but not right now. I will do that and send to you as soon as reach the lab. Meanwhile, let's try the pullups configuration. Please, teach me how to check and disable them.

    Thank you.

  • You'll need to set the appropriate bits in the GPxPUD register. See the GPIO section of SPRUFN3.

  • Hi Sam,

    I did as you asked: Disabled the pullup resistors in all four pins of SPI, namely GPIOs 16, 17, 18 and 19, but no success so far.

    Sam Friedman said:

    You'll need to set the appropriate bits in the GPxPUD register. See the GPIO section of SPRUFN3.

    I found this other POST, in which another user reports the same problem, but with a different processor. What is the problem with C2000 SPI working as slave? It seems that it is not exclusive of my processor, but the SPI module itself of C2000 processors. We got to solve this and share with the community. Any other ideas?
  • Hi Filipe,

    I will try to reproduce this on my end. I have used the SPI module as a slave successfully before, though not on this particular processor.

    In the mean time, could you send me your code? If you do not wish to post it here publicly, you can send it to me in a direct message. After adding me as a "friend" go to my profile and click the "start conversation" button.

    Regards,

    Sam

  • Hi Sam,


    Yes I can, not a problem. I did not do it yet because the code is separated in many files, but I will try to synthesize it here. Could you send a minimal example of the use of the SPI module as slave? If you have access to C2000 Piccolo Launchpads to test, one as master and the other as slave, it would be great. Also, if the example works, it could be added to Control Suite to help other users, once the example provided are only in the loop-back mode, which has to be in master mode, and is also useless unless for testing purposes.

    Here is the code:

    /*GPIO REGISTERS CONFIGURATION*/
    EALLOW;
    GpioCtrlRegs.GPAMUX1.all &= 4294967040U;
    GpioCtrlRegs.GPADIR.all |= 15U;
    EDIS;
    
    /*SPI REGISTERS CONFIGURATION*/
    
    void init_SPI_GPIO(void)
    {
      EALLOW;
      GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;  /* Enable pull-up on GPIO18 (SPICLKA)*/
      GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; /* Configure GPIO18 as SPICLKA*/
      GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;  /* Enable pull-up on GPIO19 (SPISTEA)*/
      GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; /* Configure GPIO19 as SPISTEA*/
      EDIS;
    }
    
    void init_SPI_A(uint16_T Mode,uint16_T BaudRateFactor,uint16_T DataBits,uint16_T
                    ClockPolarity,uint16_T ClockPhase,uint16_T FIFOTransmitDelay)
    {
      EALLOW;
    
      /* initialize SPI_A FIFO registers */
      SpiaRegs.SPICCR.bit.SPISWRESET = 0;  /* SPI S/W Reset, bit 7*/
      SpiaRegs.SPICCR.bit.SPICHAR = 15;/* Character length control, bit 0~3  */
      SpiaRegs.SPICCR.bit.SPILBK = 0;      /* Configure SPI for normal mode, bit 4    */
      SpiaRegs.SPICCR.bit.CLKPOLARITY = 1;/* Clock polarity, bit 6, 1:Data is output on falling edge and input on rising edge.
                                                           Clock polarity, bit 6, 0:Data is output on rising edge and input on falling edge.*/
      SpiaRegs.SPICTL.bit.TALK = 1;        /* Master/Slave transmit enable, bit 1,*/
      SpiaRegs.SPICTL.bit.MASTER_SLAVE = 0;/* Network control mode, bit 2 - SPI configured as a slave.    */
      SpiaRegs.SPICTL.bit.CLK_PHASE = 0;/* Clock phase select, bit 3 - 0: Data is output on the rising/falling edge
                                                      Clock phase select, bit 3 - 1: Data is output one half-cycle before the first rising/falling edge*/
    
      /*Free run, continue SPI operation regardless of suspend*/
      SpiaRegs.SPIPRI.bit.FREE = 1;        /* Free emulation mode control, bit 4 = 1         */
      SpiaRegs.SPIBRR = BaudRateFactor;    /* Baud rate, bit 								*/
      SpiaRegs.SPIFFTX.bit.SPIFFENA = 1;   /* SPI_A FIFO mode*/
      SpiaRegs.SPIFFRX.bit.RXFFIENA = 1;   /* SPI_A Rx Interrupt mode*/
      SpiaRegs.SPIFFRX.bit.RXFFIL = 4;     /* Enable SPI_A Rx FIFO Interrupt Level*/
      SpiaRegs.SPIFFCT.all= FIFOTransmitDelay;/* FIFO transmit delay*/
      SpiaRegs.SPICCR.bit.SPISWRESET = 1;  /* Enable SPI*/
      EDIS;
    }
    
    /*BOARD INITIALIZATION*/
    void init_board ()
    {
      DisableDog();
      EALLOW;
      SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;/* Enable ADC peripheral clock*/
      (*Device_cal)();
      SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 0;/* Return ADC clock to original state*/
      EDIS;
    
      /* Select Internal Oscillator 1 as Clock Source (default), and turn off all unused clocks to
       * conserve power.
       */
      IntOsc1Sel();
    
      /* Initialize the PLL control: PLLCR and DIVSEL
       * DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2802x_Examples.h
       */
      InitPll(12,2);
      InitPeripheralClocks();
      EALLOW;
    
      /* Configure low speed peripheral clocks */
      SysCtrlRegs.LOSPCP.all = 0U;
      EDIS;
    
      /* Disable and clear all CPU interrupts */
      DINT;
      IER = 0x0000;
      IFR = 0x0000;
      InitPieCtrl();
      InitPieVectTable();
    
      /* initial SPI function.... */
      init_SPI_GPIO();
    
      /* Initialize SPI_AModule with following parameters:
       *    Mode          : 2, Master=1, Slave=2,
       *    BaudRateFactor: 127
       *    DataBits      : 16
       *    ClockPolarity : Rising_edge
       *    ClockPhase    : No_delay
       *    FIFOTransmitDelay :  0 */
      init_SPI_A (2, 127, 16, 1, 1,0);
      InitCpuTimers();
    
      /* initial GPIO qualification settings.... */
      EALLOW;
      GpioCtrlRegs.GPAQSEL1.all = 0U;
      GpioCtrlRegs.GPAQSEL2.all = 0U;
      GpioCtrlRegs.GPBQSEL1.all = 0U;
      EDIS;
    }
    
    /* SPI Receive FIFO Interrupt Routine 
       Interrupt Level: 4 */	
    void isr_int6pie1_task_fcn(void)
    	{
         if (SpiaRegs.SPIFFRX.bit.RXFFST >= 4.0) {
              /* Data length = 16 Bits,*/
              DSP_B_B.SPIReceive[0] = SpiaRegs.SPIRXBUF;
    
              DSP_B_B.SPIReceive[1] = SpiaRegs.SPIRXBUF;
    
              DSP_B_B.SPIReceive[2] = SpiaRegs.SPIRXBUF;
    
              DSP_B_B.SPIReceive[3] = SpiaRegs.SPIRXBUF;}
    	}
    	
    /*Step function 1ms period*/	
    void DSP_B_step(void){ 
               
          int i= 0;
    	  /*SPI transmit only if FIFO TX buffer and SPITXBUFF are empty*/
          if ((SpiaRegs.SPIFFTX.bit.TXFFST == 0)&&(SpiaRegs.SPISTS.bit.BUFFULL_FLAG == 0)) {                       
            for (i = 0; i < 5; i++) {      
              /* Data length = 16 Bits*/
    		  //Constant value vector [0x001,0x002,0x003,0x004]
              SpiaRegs.SPITXBUF = DSP_B_P.Constant1_Value[i]; 
            }
          }
        }

    I contacted the user who posted the other post I cited before. He told me that the datasheet (I don't know which, I asked him and I am waiting the answer) says it is a standard read (0xFFFF) when something is not multiplexed correctly. Do you know something about that? Thanks.

  • Hi Filipe,

    A few things pop out at me from your code.

    First, in your init_SPI_GPIO() function, you mux the clock and STE signals, but not MOSI or MISO. 

    Second, you set the input qualification on all IOs to be 0, which is synchronized to the system clock. For the SPI pins, set the qualification to 3, which is asynchronous. This mode is used to allow the signals to be read directly by the SPI module, without any sort of synchronization delay or glitches from the GPIO module.

    Let me know if these changes solve your issues. If not, I'll move ahead with my own tests.

    Regards,
    Sam

  • Dear Sam,

    Thank you very much. Your guidance helped me to solve the problem.

    Indeed, the MISO and MOSI pins were not correctly adjusted in the MUX settings (what makes me look silly). However, it did not solve the problem immediately, I had to set opposite clock settings in the master and in the slave, one trailing and the other rising, and, I don't know why, that finally corrected the problem.

    Thank you very much. Keep in mind the suggestion of a practical example to add in Control Suite. Thanks. Until next time!

     

  •  Filipe Taveiros

    Great Thanks.

    " For the SPI pins, set the qualification to 3, which is asynchronous" was the solution for my question.

    Best Regards

  • I think there is a bug for "GPIO_setQualification". That function write previous settings. You may write your own "GPIO_setQualification" function.

    Best
    Goksel