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.

TMS320F28069M: problem with SPI

Part Number: TMS320F28069M

Hello,

I am using the TMS320F28069M to communicate with AS5048A (Magnetic Rotary Encoder). According to AS5048A and TMS320F28069M datasheets, the proper settings for CLOCK POLARITY and CLOCK PHASE are CLOCK POLARITY=CLOCK PHASE =0. but when I do this setting, it doesn't work. But in system turning on, when I first set CLOCK POLARITY=0 and CLOCK PHASE=1 (wrong value) and run the program and then stop the program and set the correct setting and run the program, the communication work properly. In fact, for correct working of SPI, I have to first program the MCU by wrong settings and stop it and then program it by correct settings. So what can I do for solving this problem.

Regards,
Mohammad.

  • Hi Mohammad,

    I checked the datasheet or the encoder and you are correct how the setting should be - transmit on the rising edge, receive on the falling edge of the clock.
    Can you describe clearly what the meaning of "it doesn't work" is for your situation? Is the data just incorrect? Does the encoder not respond at all?
    If you scope the signals, what do they look like - please share them here?
    Is your current workaround the only way you have been able to get the communication to work? i.e. has it ever worked the first time with the correct settings?
    What is the configuration of your SPISTE signal? Is it properly being set high between each 16bit command?

    Thanks,
    Mark
  • Thanks for response,

    1-)Meaning of "it doesn't work" is: I just read 0 in SPIRXBUF register.also, when I set the wrong value, I read data between  8192-16384 and even it change with  rotation of magnet, But this data is invalid because the right data is between  0-16384 (14 bit). Unfortunately I don't  have digital analyzer to scope the signals.

    2-) Yes, setting the wrong value at first time is my only solution to make the SPI working, and it has  never worked the first time with the correct settings.

    3-) Yes, in the start of  communication I clear the SSn and in the end of communication I set the SSn. even I add a little delay after SSn=1 but it has no effect .the following codes are my settings for SPI and reading  of encoder.

    void AS5048A_motor1(void)
    {
    EALLOW;

    GpioCtrlRegs.GPAQSEL2.bit.GPIO16 =3; // Asynch input GPIO16 (SPISIMOA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO17 =3; // Asynch input GPIO17 (SPISOMIA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO18 =3; // Asynch input GPIO18 (SPICLKA)
    GpioCtrlRegs.GPBQSEL1.bit.GPIO44 =3; // Asynch input GPIO44 (Slave select)

    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
    GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 0; // Configure GPIO44 as GPIO for Slave select
    GpioCtrlRegs.GPBDIR.bit.GPIO44 = 1; //output

    EDIS;

    SpiaRegs.SPICCR.bit.SPISWRESET=0; //reset
    SpiaRegs.SPICCR.bit.CLKPOLARITY=0;
    SpiaRegs.SPICTL.bit.CLK_PHASE=0;
    SpiaRegs.SPICCR.bit.SPILBK=0; //Loop back disable
    SpiaRegs.SPICCR.bit.SPICHAR=0xF; //16 bit Character Length
    SpiaRegs.SPICTL.bit.OVERRUNINTENA=0;
    SpiaRegs.SPICTL.bit.SPIINTENA=0;
    SpiaRegs.SPICTL.bit.MASTER_SLAVE=1; //master
    SpiaRegs.SPICTL.bit.TALK=1; //4 wire
    SpiaRegs.SPIBRR =10; //SPICLK=LSPCLK/(SPIBRR+1)-->SPICLK=(90/4)/(10+1)=2Mhz
    SpiaRegs.SPIPRI.bit.FREE = 1;
    SpiaRegs.SPIPRI.bit.SOFT = 0;
    SpiaRegs.SPIPRI.bit.STEINV = 1; 
    SpiaRegs.SPIPRI.bit.TRIWIRE = 0;
    SpiaRegs.SPICCR.bit.SPISWRESET=1;

    }


    void EN_AS5048A_SPI_motor1(void)
    {
    EALLOW;
    GpioDataRegs.GPBCLEAR.bit.GPIO44 = 1; // EN_AS5048A
    EDIS;
    }

    void DIS_AS5048A_SPI_motor1(void)
    {
    EALLOW;
    GpioDataRegs.GPBSET.bit.GPIO44 = 1; // DIS_AS5048A
    EDIS;
    DELAY_US(1);
    }


    Uint16 AS5048A_SPI_Read(Uint16 address_data)
    {
    Uint16 x;
    Uint16 R;
    union AS5048A_SPI_WRITE_WORD_REG w;
    w.bit.R_W = 1; // read - 1
    //////////////
    x=address_data;
    x ^= x >> 8;
    x ^= x >> 4;
    x ^= x >> 2;
    x ^= x >> 1;
    w.bit.PAR =((x) & 1); // parity
    w.bit.ADDRESS_DATA = address_data; // address_data
    EN_AS5048A_SPI_motor1();
    SpiaRegs.SPITXBUF=w.all;
    while(SpiaRegs.SPISTS.bit.INT_FLAG==0); // wait for the packet to complete
    DIS_AS5048A_SPI_motor1();
    EN_AS5048A_SPI_motor1();
    R=SpiaRegs.SPIRXBUF;
    DIS_AS5048A_SPI_motor1();

    }

    Regards,

    Mohammad.

  • Mohammad,

    it seems like you are on the right track, however your read command is probably incorrect. It does not explain why it using a different SPI mode works, but I don't know what would happen on the slave if you send the wrong data.

    The process it looks like that encoder requires is described in the datasheet Figure 23.
    1. Transmit Read0 command / store or discard RX read-1 data
    2. Transmit Read1 command / store RX Read0 data
    3. Transmit Read2 command / store RX Read1 data.

    For some reason you are
    1. enable CS
    2. Transmit Read0 command
    3. disable CS
    4. enable CS
    5. reading RX buffer << no data is actually transmitted here!! you are merely reading a register and storing it in 'R'
    6. disable CS

    My thoughts are that steps 4-6 are corrupting the encoder, since you are toggling the CS without transferring any data.

    My suggestion:
    1. enable CS
    2. transmit command
    3. wait for complete packet
    4. read/store received data
    5. disable CS

    It will be very difficult to continue to debug if we are not able to observe any signals. Please look into getting a hold of an oscilloscope or logic analyzer for any additional debug. This is doubly true when you are having questions about transmit/receive timings. if you cannot see when data is switched, how do you know it is misbehaving?

    -Mark
  • Was my previous suggestion helpful? Are you still facing the issue?

    Thanks,
    Mark
  • Hello,

    Thanks for response,

    I finally resoled my issue, and the problem was two thins;
    1-) wrong EN/DIS of CS as you mentioned;
    2-) I was calculating the parity bit just for address while the right parity calculation is for address+read/Write.

    Regards,

    Mohammad.
  • Glad you were able to figure it out!

    -Mark