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.

TMS320F28035: Data not being read with SPI from RDC

Part Number: TMS320F28035


Tool/software:

I have attached the code I am using to use SPI communication protocol to read the position data of the BLDC motor using EVAL - AD2S1210SDZ. The SPI communication is working fine, however no data is getting collected(posData). 

#include "DSP28x_Project.h"
#include "DSP2803x_Device.h"     // DSP2803x Header file Include File
#include "DSP2803x_Examples.h"   // DSP2803x Examples Include File
#include "DSP2803x_CpuTimers.h" // CPU Timer header
#include "resolver.h"

typedef unsigned int bool;
#define true 1
#define false 0

volatile Uint16 transmittedData = 0x00;
volatile Uint16 receivedData;
volatile Uint16 posData;  // Declare posData
volatile Uint16 velData;  // Declare velData
volatile bool dataReceived = false;

void SPI_Write(Uint16 address, Uint16 data);  // Function prototype
Uint16 SPI_Read(Uint16 address, Uint8 mode);
void SetMode(Uint16 mode);
void AD2S1210_Config(void);
void InitGpio(void);
void InitTimer(void);
void InitSPI(void);
void InitSpiGpio(void);

__interrupt void cpu_timer0_isr(void);
__interrupt void SPI_RX_ISR(void);
__interrupt void SPI_TX_ISR(void);

void main(void)
{
    InitSysCtrl();             // Initialize the system control
    InitSpiaGpio();
    DINT;                      // Disable CPU interrupts
    InitPieCtrl();             // Initialize the PIE control registers
    IER = 0x0000;              // Disable CPU interrupts
    IFR = 0x0000;              // Clear all CPU interrupt flags
    InitPieVectTable();        // Initialize the PIE vector table

    EALLOW;
    PieVectTable.TINT0 = &cpu_timer0_isr; // Map ISR function
    PieVectTable.SPIRXINTA = &SPI_RX_ISR;
    PieVectTable.SPITXINTA = &SPI_TX_ISR;
    EDIS;

    InitGpio();                // Initialize GPIO
    InitTimer();               // Initialize the timer
    InitSPI();                 // Initialize SPI

    IER |= M_INT1;             // Enable CPU INT1
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // Enable PIE Group 1 INT7

    EINT;                      // Enable Global interrupt INTM
    ERTM;                      // Enable Global real time interrupt DBGM

    AD2S1210_Config();         // Configure AD2S1210

    while(1)
    {
        // Main Loop

    }
}

void InitGpio(void)
{
    EALLOW;
    GpioCtrlRegs.GPAMUX1.bit.GPIO0       = 0;   // GPIO functionality
    GpioCtrlRegs.GPADIR.bit.GPIO0        = 1;   // GPIO0 as output

    GpioCtrlRegs.GPAPUD.bit.GPIO1        = 0;   // Enable pull-up on GPIO1
    GpioDataRegs.GPASET.bit.GPIO1        = 1;   // Load output latch
    GpioCtrlRegs.GPAMUX1.bit.GPIO1       = 0;   // GPIO1 = GPIO1
    GpioCtrlRegs.GPADIR.bit.GPIO1        = 1;   // GPIO1 as output

    GpioCtrlRegs.GPAPUD.bit.GPIO3        = 0;   // Enable pullup on GPIO3
    GpioDataRegs.GPASET.bit.GPIO3        = 1;   // Load output latch
    GpioCtrlRegs.GPAMUX1.bit.GPIO3       = 0;   // GPIO3 = GPIO3
    GpioCtrlRegs.GPADIR.bit.GPIO3        = 1;   // GPIO3 as output

    /*GpioCtrlRegs.GPAPUD.bit.GPIO20       = 0;   // Enable pull-up on GPIO20 (WR/FSYNC)
    GpioDataRegs.GPASET.bit.GPIO20       = 1;   // Load output latch
    GpioCtrlRegs.GPAMUX2.bit.GPIO20      = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO20       = 1;   // GPIO20 as output*/

    GpioCtrlRegs.GPAPUD.bit.GPIO23       = 0;   // Enable pull-up on GPIO23 (SAMPLE)
    GpioDataRegs.GPASET.bit.GPIO23       = 1;   // Load output latch
    GpioCtrlRegs.GPAMUX2.bit.GPIO23      = 0;   // GPIO3 = GPIO3
    GpioCtrlRegs.GPADIR.bit.GPIO23       = 1;   // GPIO23 as output
    EDIS;
}

void InitTimer(void)
{
    EALLOW;
    CpuTimer0Regs.PRD.all = 600000; // Set timer period (3 ms)
    CpuTimer0Regs.TCR.bit.TSS = 1; // Stop timer
    CpuTimer0Regs.TCR.bit.TRB = 1; // Reload timer
    CpuTimer0Regs.TCR.bit.TIE = 1; // Enable timer interrupt
    CpuTimer0Regs.TCR.bit.TSS = 0; // Start timer
    EDIS;
}

__interrupt void cpu_timer0_isr(void)
{
    CpuTimer0.InterruptCount++;
    // Toggle GPIO0
    GpioDataRegs.GPATOGGLE.bit.GPIO0 = 1;

    GpioDataRegs.GPATOGGLE.bit.GPIO23 = 1; //Sample pin toggling

    // Enter Normal mode—position output
     posData = SPI_Read(POS_LOW_ADDRESS, 0);

    // Acknowledge this interrupt to receive more interrupts from group 1
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

__interrupt void SPI_RX_ISR(void)
{
    receivedData = SpiaRegs.SPIRXBUF;   // Read received data
    dataReceived = true;                // Set flag indicating data received
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP6; // Acknowledge interrupt
}

__interrupt void SPI_TX_ISR(void)
{
    SpiaRegs.SPITXBUF = transmittedData; // Transmit data
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP6; // Acknowledge interrupt
}
// file end



void InitSPI(void)
{
    EALLOW;
    // Reset SPI
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;

    // Initialize SPI-A
    SpiaRegs.SPICCR.all            =    0x000F;       // Reset on, rising edge, 16-bit char bits
    SpiaRegs.SPICTL.all            =    0x0006;       // Enable master mode, normal phase, enable talk
    SpiaRegs.SPIBRR                =    0x0005;       // Baud rate for SPI clock
    SpiaRegs.SPICCR.all            =    0x008F;       // Relinquish SPI from reset
    SpiaRegs.SPIPRI.bit.FREE       =    1;            // Set so breakpoints don't disturb xmission

    // Enable SPI
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;

    // Enable SPI interrupts
    SpiaRegs.SPICTL.bit.SPIINTENA = 1;  // Enable SPI interrupt
    //PieCtrlRegs.PIEIER6.bit.INTx1 = 1;  // Enable PIE Group 6, INT1 (SPIA RX)
    //PieCtrlRegs.PIEIER6.bit.INTx2 = 1;  // Enable PIE Group 6, INT2 (SPIA TX)
    IER |= M_INT6;                      // Enable CPU INT6 (for SPI)

    EDIS;
}

//---------------------------------------------------------------------------
// Example: InitSpiGpio:
//---------------------------------------------------------------------------
// This function initializes GPIO pins to function as SPI pins
//
void InitSpiGpio()
{
    InitSpiaGpio();
}

void InitSpiaGpio()
{
    EALLOW;

    // Enable internal pull-up for the selected pins
    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;   // Enable pull-up on GPIO16 (SPISIMOA)
    GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;   // Enable pull-up on GPIO17 (SPISOMIA)
    GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;   // Enable pull-up on GPIO18 (SPICLKA)
    GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;   // Enable pull-up on GPIO19 (SPISTEA)


    // Set qualification for selected pins to asynch only
    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.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA)

    // Configure SPI-A pins using GPIO regs
    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.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA

    GpioDataRegs.GPACLEAR.bit.GPIO19       = 1;
    EDIS;
}

//===========================================================================
// End of file.
//===========================================================================

// resolver.c
#include "DSP28x_Project.h"
#include "DSP2803x_Spi.h"
#include "resolver.h"

void SPI_Write(Uint16 address, Uint16 data) {
    SetMode(3);
    DELAY_US(20);

    while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG); // Wait if buffer is full
    SpiaRegs.SPITXBUF = address; // Transmit data

    while(SpiaRegs.SPISTS.bit.INT_FLAG != 1)
    {
        /* wait till SPI has completed sending or receiving */
    }

    while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG); // Wait if buffer is full
    SpiaRegs.SPITXBUF = data; // Transmit data

    SetMode(0);
}

Uint16 SPI_Read(Uint16 address, Uint8 mode) {
    SetMode(3);
    DELAY_US(20);

    while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG); // Wait if buffer is full
    SpiaRegs.SPITXBUF = address; // Transmit address

    SetMode(mode);

    while (!SpiaRegs.SPISTS.bit.INT_FLAG); // Wait for data to be received
    receivedData = SpiaRegs.SPIRXBUF; // Read received data

    return receivedData;
}


void SetMode(Uint16 mode) {
    switch (mode) {
        case 0: // Normal mode—position output
            GpioDataRegs.GPACLEAR.bit.GPIO1 = 1; // Set A0 low
            GpioDataRegs.GPACLEAR.bit.GPIO3 = 1; // Set A1 low
            break;
        case 1: // Normal mode—velocity output
            GpioDataRegs.GPACLEAR.bit.GPIO1 = 1; // Set A0 low
            GpioDataRegs.GPASET.bit.GPIO3   = 1; // Set A1 high
            break;
        case 2: // Reserved
            GpioDataRegs.GPASET.bit.GPIO1   = 1; // Set A0 high
            GpioDataRegs.GPACLEAR.bit.GPIO3 = 1; // Set A1 low
            break;
        case 3: // Configuration mode
            GpioDataRegs.GPASET.bit.GPIO1   = 1; // Set A0 high
            GpioDataRegs.GPASET.bit.GPIO3   = 1; // Set A1 high
            break;
        default:
            // Handle invalid mode
            break;
    }
}

void AD2S1210_Config(void) {
    SPI_Write(AD2S1210_EXCIT_FREQ, 5); // frequency control word for 10 kHz
}
//resolver.c ends here


// resolver.h
#ifndef RESOLVER_H
#define RESOLVER_H

#define POS_HIGH_ADDRESS               0x80  // D15 to D8 (Read only)
#define POS_LOW_ADDRESS                0x81  // D7 to D0 (Read only)
//#define VEL_HIGH_ADDRESS               0x82  // D15 to D8 (Read only)
#define VEL_LOW_ADDRESS                0x83  // D7 to D0 (Read only)

#define AD2S1210_LOS_THRD               0x88
#define AD2S1210_DOS_OVR_THRD           0x89
#define AD2S1210_DOS_MIS_THRD           0x8A
#define AD2S1210_DOS_RST_MAX_THRD       0x8B
#define AD2S1210_DOS_RST_MIN_THRD       0x8C
#define AD2S1210_LOT_HIGH_THRD          0x8D
#define AD2S1210_LOT_LOW_THRD           0x8E
#define AD2S1210_EXCIT_FREQ             0x91
#define AD2S1210_CONTROL                0x92
#define AD2S1210_SOFT_RESET             0xF0
#define AD2S1210_FAULT                  0xFF

extern volatile Uint16 receivedData; // Declare receivedData as extern

void SPI_Write(Uint16 address, Uint16 data);
Uint16 SPI_Read(Uint16 address, Uint8 mode);
void SetMode(Uint16 mode);
void AD2S1210_Config(void);

#endif // RESOLVER_H

  • Hello,

    Apologies for the delay, I unexpectedly out of office.

    The information provided is reasonably comprehensive, thank you very much for that! A few debug questions and notes to clarify the situation:

    1. During runtime, is the value of CpuTimer0.InterruptCount incrementing correctly? This tells us whether the interrupt is actually executing. If not, that should be focused on first.

    2. During runtime, after running for a bit, what is the state of the (presumably) boolean var dataReceived ? If SPI_RX_ISR is triggering, then it's possible the SPIA Rx buffer is being read at the incorrect time, and the SPI_Read() function will not give you meaningful information.

    3. If you have a signal analyzer or oscilloscope, monitoring the Rx line to verify that information is being sent over properly would be ideal to verify incoming signal integrity.

    Regards,
    Jason Osborn