TMS320F28379D: Reading Default Register Values from ADS1258 via SPI on TMS320F28379D

Part Number: TMS320F28379D
Other Parts Discussed in Thread: ADS1258

Tool/software:

Hello,

   I am working on the TMS320F28379D controller and I want to interface it with the ADS1258 via SPI. The main task is to read the default register values of the ADS1258. I have provided the code below, so please let me know what is wrong in it.

//###########################################################################
//
// FILE: Example_2837xDSpi_FFDLB.c
//
// TITLE: SPI Digital Loop Back program.
//
//! \addtogroup cpu01_example_list
//! <h1>SPI Digital Loop Back (spi_loopback)</h1>
//!
//! This program uses the internal loop back test mode of the peripheral.
//! Other then boot mode pin configuration, no other hardware configuration
//! is required. Interrupts are not used.
//!
//! A stream of data is sent and then compared to the received stream.
//! The sent data looks like this: \n
//! 0000 0001 0002 0003 0004 0005 0006 0007 .... FFFE FFFF \n
//! This pattern is repeated forever.
//!
//! \b Watch \b Variables \n
//! - \b sdata - sent data
//! - \b rdata - received data
//!
//
//###########################################################################
//
//
// $Copyright:
// Copyright (C) 2013-2024 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################

//
// Included Files
//
#include "F28x_Project.h"
#include "ADS1258.h"

//
// Function Prototypes
//
void transmitData(uint16_t a);
void initSPIFIFO(void);
void error(void);
void InitSpi(void);
void InitSpiaGpio(void);
void InitADS1258Gpio(void);
void ADS1258_Reset(void);
void ADS1258_ReadRegisters(int start_addr, int num, int* buffer);
uint16_t spiTransfer(uint16_t data);

int i;
int regs[2];
int registerMap[NUM_REGISTERS];

void main(void)
{

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
//
InitSysCtrl();

// Step 2. Initialize GPIO:
// This example function is found in the F2837xD_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// Setup only the GP I/O only for SPI-A functionality
// This function is found in F2837xD_Spi.c
//
InitSpiaGpio();
InitADS1258Gpio();

// Step 3. Clear all interrupts:
//
DINT;

// Initialize PIE control registers to their default state.
// The default state is all PIE __interrupts disabled and flags
// are cleared.
// This function is found in the F2837xD_PieCtrl.c file.
//
InitPieCtrl();

// Disable CPU __interrupts and clear all CPU __interrupt flags:
//
IER = 0x0000;
IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the __interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
//
InitPieVectTable();

//
// Step 4. Initialize the Device Peripherals:
//
spi_fifo_init(); // Initialize the SPI FIFO

adcStartupRoutine();

for(;;)
{
}
}

//
// delay_loop - Loop for a brief delay
//
void delay_loop()
{
long i;
for (i = 0; i < 1000000; i++) {}
}

//
// error - Error function that halts the debugger
//
void error(void)
{
asm(" ESTOP0"); // Test failed!! Stop!
for (;;);
}

//
// spi_xmit - Transmit value via SPI
//
void spi_xmit(Uint16 a)
{
SpiaRegs.SPITXBUF = a;
}

uint16_t spiTransfer(uint16_t data)
{
while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG);
SpiaRegs.SPITXBUF = data;
while(SpiaRegs.SPISTS.bit.INT_FLAG == 0);
return SpiaRegs.SPIRXBUF;
}

//
// spi_fifo_init - Initialize SPIA FIFO
//
void spi_fifo_init()
{
//
// Initialize SPI FIFO registers
//
SpiaRegs.SPIFFTX.all = 0xE040;
SpiaRegs.SPIFFRX.all = 0x2044;
SpiaRegs.SPIFFCT.all = 0x0;

//
// Initialize core SPI registers
//
InitSpi();
}

void InitADS1258Gpio(void)
{
EALLOW;

GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0; // GPIO80 as GPIO
GpioCtrlRegs.GPBDIR.bit.GPIO52 = 1; // Output (PWDN)

GpioCtrlRegs.GPDMUX1.bit.GPIO97 = 0; // GPIO84 as GPIO
GpioCtrlRegs.GPDDIR.bit.GPIO97 = 1; // Output (RESET)

GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 0; // GPIO4 as GPIO
GpioCtrlRegs.GPCDIR.bit.GPIO67 = 1; // Output (START)

EDIS;

}

void adcStartupRoutine(void)
{
/* (OPTIONAL) Provide additional delay time for power supply settling */
DELAY_US(50000); //5ms

/* (REQUIRED) Set nRESET/nPWDN pin high for ADC operation */
GpioDataRegs.GPBCLEAR.bit.GPIO52 = 1;

/* (OPTIONAL) Start ADC conversions with HW pin control */
GpioDataRegs.GPCCLEAR.bit.GPIO67 = 1;

/* (REQUIRED) tWAKE delay */
DELAY_US(50000);

/* (OPTIONAL) Toggle nRESET pin to assure default register settings. */
/* NOTE: This also ensures that the device registers are unlocked. */
GpioDataRegs.GPDCLEAR.bit.GPIO97 = 1; // RESET low
DELAY_US(10);
GpioDataRegs.GPDSET.bit.GPIO97 = 1; // RESET high
DELAY_US(10);

/* Ensure internal register array is initialized */
// restoreRegisterDefaults();

/* (OPTIONAL) Configure initial device register settings here*/
// uint8_t initRegisterMap[NUM_REGISTERS];
// initRegisterMap[REG_ADDR_CONFIG0] = CONFIG0_DEFAULT;
// initRegisterMap[REG_ADDR_CONFIG1] = CONFIG1_DLY_64us | CONFIG1_DRATE_7813SPS;
// initRegisterMap[REG_ADDR_MUXSCH] = MUXSCH_DEFAULT;
// initRegisterMap[REG_ADDR_MUXDIF] = MUXDIF_DEFAULT;
// initRegisterMap[REG_ADDR_MUXSG0] = MUXSG0_DEFAULT;
// initRegisterMap[REG_ADDR_MUXSG1] = MUXSG1_DEFAULT;
// initRegisterMap[REG_ADDR_SYSRED] = SYSRED_DEFAULT;
// initRegisterMap[REG_ADDR_GPIOC] = GPIOC_DEFAULT;
// initRegisterMap[REG_ADDR_GPIOD] = GPIOD_DEFAULT;
// initRegisterMap[REG_ADDR_ID] = 0x00; // Read-only register

/* (OPTIONAL) Write to all (writable) registers */
//writeMultipleRegisters(REG_ADDR_CONFIG0, NUM_REGISTERS - 1, initRegisterMap);

/* (OPTIONAL) Read back all registers */
// readMultipleRegisters(REG_ADDR_CONFIG0, NUM_REGISTERS);
//
// Read first 2 registers (0x00 and 0x01)
//
ADS1258_ReadRegisters(0x00, 2, regs);

/* (OPTIONAL) Start ADC conversions with the SPI command.
* Not needed if the START pin has already been set HIGH.
*
* sendCommand(START_OPCODE);
*/
}

//void writeMultipleRegisters(uint8_t startAddress, uint8_t count, const uint8_t regData[])
//{
// /* Check that the register address and count are in range */
// assert(startAddress + count <= NUM_REGISTERS);
//
// /* Check that regData is not a NULL pointer */
// assert(regData);
//
//
// //
// // SPI communication
// //
//
// GpioDataRegs.GPBSET.bit.GPIO61 = 0;
//
// uint8_t dataTx = OPCODE_WREG | OPCODE_MUL_MASK | (startAddress & OPCODE_A_MASK);
// spiSendReceiveByte(dataTx);
//
// uint8_t i;
// for (i = startAddress; i < startAddress + count; i++)
// {
// // write register data bytes
// spiSendReceiveByte(regData[i]);
//
// /* Update register array */
// registerMap[i] = regData[i];
// }
//
// GpioDataRegs.GPBSET.bit.GPIO61 = 1;
//}

void readMultipleRegisters(int startAddress, int count)
{
/* Check that the register address and count are in range */
assert(startAddress + count <= NUM_REGISTERS);

//
// SPI communication
//
GpioDataRegs.GPBSET.bit.GPIO61 = 0;

int dataTx = OPCODE_RREG | OPCODE_MUL_MASK | (startAddress & OPCODE_A_MASK);
spiTransfer(dataTx);

int i;
for (i = startAddress; i < startAddress + count; i++)
{
// Read register data bytes
registerMap[i] = spiTransfer(0x00);
}

GpioDataRegs.GPBSET.bit.GPIO61 = 1;
}


//
// Read Registers from ADS1258
//
void ADS1258_ReadRegisters(int start_addr, int num, int* buffer)
{
spiTransfer(0x10 | (start_addr & 0x0F)); // READ REG command
spiTransfer(num - 1); // Number of registers - 1

for ( i = 0; i < num; i++)
{
buffer[i] = (int)spiTransfer(0x00); // Read register
}

GpioDataRegs.GPASET.bit.GPIO19 = 1; // CS high
}

  • Hello, and apologies for the delay in response.

    A couple things. First, please try not to paste code directly- use the insert->code functionality instead. This can cause issues with system performance otherwise. Second, what is the incorrect behavior you're seeing? Is the code compiling? Is the SPI clock not running? Is there incorrect data in the Rx register? I need more information to properly diagnose this problem.

    Regards,
    Jason Osborn

  • I have set the SPI clock frequency to 1 MHz, and I have verified it on the oscilloscope—it is correct.
    However, I am unable to read any default register values; the data always shows as 00.

    Now, what hardware-related things should I check in this case?

    Also, please verify whether my SPI settings in the code are correct for the ADS1258
    specifically, the CPOL and CPHA (Clock Polarity and Phase) bits.
     Can you check whether I’ve made any mistake in my code related to SPI settings?

    #include "F28x_Project.h"
    #include "ADS1258.h"
    
    void transmitData(uint16_t a);
    void initSPIFIFO(void);
    void error(void);
    void InitSpi(void);
    void InitSpiaGpio(void);
    void InitADS1258Gpio(void);
    void ADS1258_Reset(void);
    void ADS1258_ReadRegisters(int start_addr, int num, int* buffer);
    uint16_t spiTransfer(uint16_t data);
    
    int i;
    int regs[2];
    int registerMap[NUM_REGISTERS];
    
    void main(void)
    {
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
    //
       InitSysCtrl();
    
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // Setup only the GP I/O only for SPI-A functionality
    // This function is found in F2837xD_Spi.c
    //
       InitSpiaGpio();
       InitADS1258Gpio();
    
    // Step 3. Clear all interrupts:
    //
       DINT;
    
    // Initialize PIE control registers to their default state.
    // The default state is all PIE __interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xD_PieCtrl.c file.
    //
       InitPieCtrl();
    
    // Disable CPU __interrupts and clear all CPU __interrupt flags:
    //
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the __interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
    //
       InitPieVectTable();
    
    //
    // Step 4. Initialize the Device Peripherals:
    //
       spi_fifo_init();     // Initialize the SPI FIFO
    
       adcStartupRoutine();
    
       for(;;)
       {
       }
    }
    
    //
    // delay_loop - Loop for a brief delay
    //
    void delay_loop()
    {
        long i;
        for (i = 0; i < 1000000; i++) {}
    }
    
    //
    // error - Error function that halts the debugger
    //
    void error(void)
    {
        asm("     ESTOP0");     // Test failed!! Stop!
        for (;;);
    }
    
    //
    // spi_xmit - Transmit value via SPI
    //
    void spi_xmit(Uint16 a)
    {
        SpiaRegs.SPITXBUF = a;
    }
    
    uint16_t spiTransfer(uint16_t data)
    {
        while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG);
        SpiaRegs.SPITXBUF = data;
        while(SpiaRegs.SPISTS.bit.INT_FLAG == 0);
        return SpiaRegs.SPIRXBUF;
    }
    
    //
    // spi_fifo_init - Initialize SPIA FIFO
    //
    void spi_fifo_init()
    {
        //
        // Initialize SPI FIFO registers
        //
        SpiaRegs.SPIFFTX.all = 0xE040;
        SpiaRegs.SPIFFRX.all = 0x2044;
        SpiaRegs.SPIFFCT.all = 0x0;
    
        //
        // Initialize core SPI registers
        //
        InitSpi();
    }
    
    void InitADS1258Gpio(void)
    {
        EALLOW;
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0;  // GPIO80 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO52 = 1;   // Output (PWDN)
    
        GpioCtrlRegs.GPDMUX1.bit.GPIO97 = 0;  // GPIO84 as GPIO
        GpioCtrlRegs.GPDDIR.bit.GPIO97 = 1;   // Output (RESET)
    
        GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPCDIR.bit.GPIO67 = 1;    // Output (START)
    
        EDIS;
    
    }
    
    void adcStartupRoutine(void)
    {
        DELAY_US(50000);
        GpioDataRegs.GPBCLEAR.bit.GPIO52 = 1;  // PWDN high
        GpioDataRegs.GPCCLEAR.bit.GPIO67 = 1;  // START high
        DELAY_US(50000);
    
        GpioDataRegs.GPDCLEAR.bit.GPIO97 = 1;  // RESET low
        DELAY_US(10);
        GpioDataRegs.GPDSET.bit.GPIO97 = 1;    // RESET high
        DELAY_US(500);
    
        // Read first two registers
        ADS1258_ReadRegisters(0x00, 2, regs);
    }
    
    void readMultipleRegisters(int startAddress, int count)
    {
        /* Check that the register address and count are in range */
        assert(startAddress + count <= NUM_REGISTERS);
    
        //
        // SPI communication
        //
        GpioDataRegs.GPBSET.bit.GPIO61 = 0;
    
        int dataTx = OPCODE_RREG | OPCODE_MUL_MASK | (startAddress & OPCODE_A_MASK);
        spiTransfer(dataTx);
    
        int i;
        for (i = startAddress; i < startAddress + count; i++)
        {
            // Read register data bytes
            registerMap[i] = spiTransfer(0x00);
        }
    
        GpioDataRegs.GPBSET.bit.GPIO61 = 1;
    }
    
    
    //
    // Read Registers from ADS1258
    //
    void ADS1258_ReadRegisters(int start_addr, int num, int* buffer)
    {
        GpioDataRegs.GPACLEAR.bit.GPIO19 = 1;               // CS low
        spiTransfer(0x10 | (start_addr & 0x0F));            // READ_REG command
        spiTransfer(num - 1);                               // Num registers - 1
        DELAY_US(10);                                       // Small delay to meet timing
    
        for (i = 0; i < num; i++)
            buffer[i] = spiTransfer(0x00);
    
        GpioDataRegs.GPASET.bit.GPIO19 = 1;                 // CS high
    }
    
    void InitSpi(void)
    {
        // Initialize SPI-A
    
        // Set reset low before configuration changes
        // Clock polarity (0 == rising, 1 == falling)
        // 16-bit character
        // Enable loop-back
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    
        SpiaRegs.SPIPRI.bit.TRIWIRE = 1;
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
        SpiaRegs.SPICCR.bit.SPICHAR = 7;
        SpiaRegs.SPICCR.bit.SPILBK = 0;
    
        // Enable master (0 == slave, 1 == master)
        // Enable transmission (Talk)
        // Clock phase (0 == normal, 1 == delayed)
        // SPI interrupts are disabled
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
        SpiaRegs.SPICTL.bit.TALK = 1;
        SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;
    
        // Set the baud rate
        SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 24;
    
        // Set FREE bit
        // Halting on a breakpoint will not halt the SPI
        SpiaRegs.SPIPRI.bit.FREE = 1;
    
        // Release the SPI from reset
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;
    }
    void InitSpiaGpio()
    {
       EALLOW;
    
        GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;  // Enable pull-up on GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;  // Enable pull-up on GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;  // Enable pull-up on GPIO18 (SPICLKA)
        GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0;  // Enable pull-up on GPIO19 (SPISTEA)
    
        GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3; // Asynch input GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3; // Asynch input GPIO18 (SPICLKA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 3; // Asynch input GPIO19 (SPISTEA)
    
        GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
        GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
    
        EDIS;
    }
    
    

  • Based on the ADS1258 timing diagram on the device datasheet page 7, there is a delay of t_dist between the data pin bit being asserted and the first rising edge of the clock, which is when the sampling is expected. Based on the F2837xD device TRM page 2263 SPICLK option descriptions, this should correspond to a rising-edge-with-delay configuration, or POL=0, PHASE=1.

    It looks like this isn't the configuration you're using. If you fix this, does it solve the issue?

    Regards,
    Jason Osborn

  • s a basic test, I'm trying to read the default value of the CONFIG0 register (address 0x00), which according to the datasheet should return 0x0A. However, I'm consistently receiving 0x0040 in the RXBUF. I've configured the SPI with CLKPOL = 0 and CLKPHA = 1 based on the ADS1258 datasheet timing diagram (page 7) and the F2837xD TRM guidance regarding tDIST, which suggests data should be sampled on the rising edge with a delay. The reset and power-up sequence I'm using is as follows: first, I set START high, then drive PWDN low → delay → high, followed by RESET low → delay → high. I verified this sequence using an oscilloscope. I’m sending 0x40 (RREG command for register 0x00) via SPI, and the waveform matches what I expect: yellow is SCLK and green is MOSI showing 0x40, though it seems to align on the falling edge. Despite trying various delays and pin sequences, I'm still not receiving the expected 0x0A. Is there an issue with the timing, CS handling, or does ADS1258 require a specific delay after RESET before communication? Any insights on what might be going wrong would be appreciated.


    #include "F28x_Project.h"
    
    typedef unsigned char uint8_t;
    
    void delay_loop(void);
    void spi_xmit(uint8_t a);
    void spi_fifo_init(void);
    void spi_init(void);
    void error(void);
    
    uint8_t sdata;  // send data
    uint8_t rdata;  // received data
    int c;
    uint8_t config0,tmp;
    Uint16 received;
    uint8_t config0_value;
    
    void main(void)
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
       InitSysCtrl();
    
    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // Setup only the GPIO only for SPI-A functionality
    // This function is found in F2837xD_Spi.c
    
       InitSpiaGpio();
       InitADS1258Gpio();
    
    //
    // Step 3. Clear all interrupts:
    //
       DINT;
    
    //
    // Initialize PIE control registers to their default state.
    // The default state is all PIE __interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xD_PieCtrl.c file.
    //
       InitPieCtrl();
    
    // Disable CPU __interrupts and clear all CPU __interrupt flags:
    //
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the __interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
    //
       InitPieVectTable();
    
    //
    // Step 4. Initialize the Device Peripherals:
    //
       spi_fifo_init();     // Initialize the SPI FIFO
    
    //
    // Step 5. User specific code:
    //
       adcStartupRoutine();
    
       GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1; // CS low
    
       DELAY_US(1);
    
       // SPI transmission:
       while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG); // Wait until TXBUF is ready
       SpiaRegs.SPITXBUF = 0x40 << 8; // RREG for CONFIG0
    
       while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG); // Wait until TXBUF is ready
       SpiaRegs.SPITXBUF = 0x00 << 8; // Read 1 register
    
       while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG); // Wait until TXBUF is ready
       SpiaRegs.SPITXBUF = 0xFF << 8; // Dummy byte to receive data
    
       config0_value = (SpiaRegs.SPIRXBUF >> 8);
    
       DELAY_US(1);
       GpioDataRegs.GPBSET.bit.GPIO61 = 1; // CS high
    
       for(;;)
       {
         
       }
    }
    
    void adcStartupRoutine(void)
    {
        /* (OPTIONAL) Provide additional delay time for pow
        * er supply settling */
        DELAY_US(50000);
        
        /* (REQUIRED) Set nRESET/nPWDN pin high for ADC operation */
        GpioDataRegs.GPBCLEAR.bit.GPIO52 = 1;  // pwdn low
        DELAY_US(100);
        GpioDataRegs.GPBSET.bit.GPIO52 = 1;  // PWDN high
        
        /* (REQUIRED) tWAKE delay */
        DELAY_US(5000);
        
        /* (OPTIONAL) Toggle nRESET pin to assure default register settings. */
        /* NOTE: This also ensures that the device registers are unlocked.   */
        GpioDataRegs.GPDCLEAR.bit.GPIO97 = 1;  // RESET low
        DELAY_US(100);
        GpioDataRegs.GPDSET.bit.GPIO97 = 1;    // RESET high
        DELAY_US(2600);
        
        /* (OPTIONAL) Start ADC conversions with HW pin control  */
        GpioDataRegs.GPCSET.bit.GPIO67 = 1;  // START high
    
    
    }
    
    //
    // delay_loop - Loop for a brief delay
    //
    void delay_loop()
    {
        long i;
        for (i = 0; i < 1000000; i++) {}
    }
    
    //
    // error - Error function that halts the debugger
    //
    void error(void)
    {
        asm("     ESTOP0");     // Test failed!! Stop!
        for (;;);
    }
    
    //
    // spi_xmit - Transmit value via SPI
    //
    void spi_xmit(uint8_t a)
    {
        SpiaRegs.SPITXBUF = (a) << 8; // move to MSB
    }
    
    //
    // spi_fifo_init - Initialize SPIA FIFO
    //
    void spi_fifo_init()
    {
        //
        // Initialize SPI FIFO registers
        //
        SpiaRegs.SPIFFTX.all = 0xE040;
        SpiaRegs.SPIFFRX.all = 0x2044;
        SpiaRegs.SPIFFCT.all = 0x0;
    
        //
        // Initialize core SPI registers
        //
        InitSpi();
    }
    
    void InitADS1258Gpio(void)
    {
        EALLOW;
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0;  // GPIO80 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO52 = 1;   // Output (PWDN)
    
        GpioCtrlRegs.GPDMUX1.bit.GPIO97 = 0;  // GPIO84 as GPIO
        GpioCtrlRegs.GPDDIR.bit.GPIO97 = 1;   // Output (RESET)
    
        GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPCDIR.bit.GPIO67 = 1;    // Output (START)
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1;    // Output (CS)
    
        EDIS;
    
    }
    void InitSpi(void)
    {
        // Initialize SPI-A
    
        // Set reset low before configuration changes
        // Clock polarity (0 == rising, 1 == falling)
        // 16-bit character
        // Enable loop-back
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    
        SpiaRegs.SPIPRI.bit.TRIWIRE = 1;
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
        SpiaRegs.SPICCR.bit.SPICHAR = 7;
        SpiaRegs.SPICCR.bit.SPILBK = 0;
    
        // Enable master (0 == slave, 1 == master)
        // Enable transmission (Talk)
        // Clock phase (0 == normal, 1 == delayed)
        // SPI interrupts are disabled
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
        SpiaRegs.SPICTL.bit.TALK = 1;
        SpiaRegs.SPICTL.bit.CLK_PHASE = 1;
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;
    
        // Set the baud rate
        SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 24;
    
        // Set FREE bit
        // Halting on a breakpoint will not halt the SPI
        SpiaRegs.SPIPRI.bit.FREE = 1;
    
        // Release the SPI from reset
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;
    }
    
    //
    // InitSpiGpio - This function initializes GPIO pins to function as SPI pins.
    //               Each GPIO pin can be configured as a GPIO pin or up to 3
    //               different peripheral functional pins. By default all pins come
    //               up as GPIO inputs after reset.
    //
    //               Caution:
    //               For each SPI peripheral
    //               Only one GPIO pin should be enabled for SPISOMO operation.
    //               Only one GPIO pin should be enabled for SPISOMI operation.
    //               Only one GPIO pin should be enabled for SPICLK  operation.
    //               Only one GPIO pin should be enabled for SPISTE  operation.
    //               Comment out other unwanted lines.
    //
    void InitSpiGpio()
    {
       InitSpiaGpio();
    }
    
    //
    // InitSpiaGpio - Initialize SPIA GPIOs
    //
    void InitSpiaGpio()
    {
       EALLOW;
    
        //
        // Enable internal pull-up for the selected pins
        //
        // Pull-ups can be enabled or disabled by the user.
        // This will enable the pullups for the specified pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;  // Enable pull-up on GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;  // Enable pull-up on GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;  // Enable pull-up on GPIO18 (SPICLKA)
        GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0;  // Enable pull-up on GPIO19 (SPISTEA)
    
        //
        // Set qualification for selected pins to asynch only
        //
        // This will select asynch (no qualification) for the selected pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3; // Asynch input GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3; // Asynch input GPIO18 (SPICLKA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 3; // Asynch input GPIO19 (SPISTEA)
    
    
        GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
        //
        //Configure SPI-A pins using GPIO regs
        //
        // This specifies which of the possible GPIO pins will be SPI functional
        // pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
        GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
    
        EDIS;
    }
    
    

  • Depending on how you're clocking the device, the ADS1258 clock is not valid for a certain amount of time after RESET is asserted. Wake-up time is described on page 24 of the device datasheet.

    To be clear- are you using the PWDN or RESET pin? The RESET pin clears registers to their default state, but PWDN explicitly does not do this.

    Additionally, referring to page 35 of the datasheet, the ADS1258 states that CS should be toggled or the SPI should be allowed to time out before sending a command to ensure integrity of the interface.

    Regards,
    Jason Osborn

  • My current task is to read the default value of the CONFIG0 register (which should be 0x0A) from the ADS1258 ADC using a TMS320F28379D microcontroller.
    I have attached my code below.

    In the first oscilloscope image:

    • Yellow shows the /CS (chip select) line, which goes from high to low.

    • Green is the SCLK line, which is set to 1 MHz.

    In the second image:

    • Yellow shows the MOSI line, where the data 0x40, 0x00, 0x00 is being transmitted (to read CONFIG0).

    • Green again shows the SCLK.

    The problem is:

    • I'm not getting any response on the DOUT (MISO) line.

    • Nothing is read into the register variable in my code.

    However, when I use the ADS1258EVM software, I'm able to read the register values correctly without issue.

    Any suggestions would be appreciated — especially if there's something I might be missing in the SPI setup, timing, or ADS1258 configuration/reset sequence.

    #include "F28x_Project.h"
    #include "ADS1258.h"
    
    uint8_t config0;
    /* Initialize arrays */
    uint8_t DataTx;
    uint8_t DataRx;
    uint8_t regVal;
    void main(void)
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // Setup only the GPIO only for SPI-A functionality
    // This function is found in F2837xD_Spi.c
       InitSpiaGpio();
       InitADS1258Gpio();
    
    // Step 3. Clear all interrupts:
       DINT;
    
    //
    // Initialize PIE control registers to their default state.
    // The default state is all PIE __interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xD_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU __interrupts and clear all CPU __interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the __interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
       InitPieVectTable();
    
    // Step 4. Initialize the Device Peripherals:
       spi_fifo_init();     // Initialize the SPI FIFO
    
    // Step 5. User specific code:
       adcStartupRoutine();
       readSingleRegister(0x00);
    
       for(;;)
       {
    
       }
    }
    
    void adcStartupRoutine(void)
    {
        /* (OPTIONAL) Provide additional delay time for power supply settling */
        DELAY_US(50000);
    
        /* (REQUIRED) Set nRESET/nPWDN pin high for ADC operation */
        GpioDataRegs.GPBCLEAR.bit.GPIO52 = 1;  // PWDN low
        DELAY_US(10);
        GpioDataRegs.GPBSET.bit.GPIO52 = 1;    // PWDN high
        DELAY_US(1000);
    
        /* (REQUIRED) tWAKE delay */
        DELAY_US(5000);
    }
    
    uint8_t spiSendReceiveByte(uint8_t dataTx)
    {
        // Wait until the transmit buffer is empty
        while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG); // Wait until TXBUF is ready
    
        // Write data to the transmit buffer
        SpiaRegs.SPITXBUF =dataTx << 8;  // Upper byte used
    }
    
    
    Uint16 SPI_Transfer(Uint16 data)
    {
        while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG);   // Wait if buffer full
        SpiaRegs.SPITXBUF = data << 8;              // Send byte
        // Wait until data is received (RX ready)
        while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
        return (SpiaRegs.SPIRXBUF & 0x00FF);        // Read received byte
    }
    
    //
    // spi_fifo_init - Initialize SPIA FIFO
    //
    void spi_fifo_init()
    {
        //
        // Initialize SPI FIFO registers
        //
        SpiaRegs.SPIFFTX.all = 0xE040;
        SpiaRegs.SPIFFRX.all = 0x2044;
        SpiaRegs.SPIFFCT.all = 0x0;
    
        //
        // Initialize core SPI registers
        //
        InitSpi();
    }
    
    void InitADS1258Gpio(void)
    {
        EALLOW;
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0;  // GPIO80 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO52 = 1;   // Output (PWDN)
    
        GpioCtrlRegs.GPDMUX1.bit.GPIO97 = 0;  // GPIO84 as GPIO
        GpioCtrlRegs.GPDDIR.bit.GPIO97 = 1;   // Output (RESET)
    
        GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPCDIR.bit.GPIO67 = 1;    // Output (START)
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1;    // Output (CS)
    
        EDIS;
    
    }
    
    uint8_t readSingleRegister(uint8_t address)
    {
       DataTx = OPCODE_RREG | (address & OPCODE_A_MASK);
    
       GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1;   // CS LOW
       spiSendReceiveByte(OPCODE_RREG | (address & 0x0F));
       spiSendReceiveByte(0x00);
       regVal = spiSendReceiveByte(0x00);     // Clock out response
    
       // Wait until data is received (RX ready)
        while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
    
       // Read received data (RXBUF is 16 bits, use upper 8 bits)
        DataRx = (SpiaRegs.SPIRXBUF >> 8);
    
       DELAY_US(10);
       GpioDataRegs.GPBSET.bit.GPIO61 = 1; // CS HIGH
       DELAY_US(10);
    
    }
    //
    // InitSPI - This function initializes the SPI to a known state
    //
    void InitSpi(void)
    {
        // Initialize SPI-A
    
        // Set reset low before configuration changes
        // Clock polarity (0 == rising, 1 == falling)
        // 16-bit character
        // Enable loop-back
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    
        SpiaRegs.SPIPRI.bit.TRIWIRE = 1;
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
        SpiaRegs.SPICCR.bit.SPICHAR = 7;
        SpiaRegs.SPICCR.bit.SPILBK = 0;
    
        // Enable master (0 == slave, 1 == master)
        // Enable transmission (Talk)
        // Clock phase (0 == normal, 1 == delayed)
        // SPI interrupts are disabled
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
        SpiaRegs.SPICTL.bit.TALK = 1;
        SpiaRegs.SPICTL.bit.CLK_PHASE = 1;
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;
    
        // Set the baud rate
        SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 24;
    
        // Set FREE bit
        // Halting on a breakpoint will not halt the SPI
        SpiaRegs.SPIPRI.bit.FREE = 1;
    
        // Release the SPI from reset
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;
    }
    
    void InitSpiGpio()
    {
       InitSpiaGpio();
    }
    
    //
    // InitSpiaGpio - Initialize SPIA GPIOs
    //
    void InitSpiaGpio()
    {
       EALLOW;
    
        //
        // Enable internal pull-up for the selected pins
        //
        // Pull-ups can be enabled or disabled by the user.
        // This will enable the pullups for the specified pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;  // Enable pull-up on GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;  // Enable pull-up on GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;  // Enable pull-up on GPIO18 (SPICLKA)
        GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0;  // Enable pull-up on GPIO19 (SPISTEA)
    
        //
        // Set qualification for selected pins to asynch only
        //
        // This will select asynch (no qualification) for the selected pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3; // Asynch input GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3; // Asynch input GPIO18 (SPICLKA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 3; // Asynch input GPIO19 (SPISTEA)
    
    
        GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
        //
        //Configure SPI-A pins using GPIO regs
        //
        // This specifies which of the possible GPIO pins will be SPI functional
        // pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
        GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
    
        EDIS;
    }

    OPCODE_RREG is 0x40.

  • I am waiting for your reply.

  • Hello and apologies for the delay in response,

    Looking through the configurations thoroughly, I see the following issue which will prevent your system from functioning, but is not the current blocking problem as far as I can tell:

    • SpiaRegs.SPIPRI.bit.TRIWIRE = 1;
      • Why are you using TRIWIRE mode if you have a separate MISO/SOMI line? Disable TRIWIRE mode, or you will never be able to read the SOMI line.

    Debug:

    • You state that when you use the ADS1258EVM software, everything is functional. Can you show me the state of the SPI pins when running the successful example?
    • I would also compare the state of your interface pins to how the EVM does it.

    As a few side notes, the following are not likely to be relevant to your issue, but are something you should look at:

    • GPIO61 configuration
      • main function calls InitSpiaGpio() and then InitADS1258Gpio() in that order 
      • InitSpiaGpio configures GPIO61 to be controlled by the SPI peripheral
        • GpioCtrlRegs.GPBGMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
        • GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA

      • InitADS1258Gpio configures GPIO61 as a regular GPIO
        • GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;   // GPIO4 as GPIO

      • The lines in InitSpiaGpio() for GPIO61 are not necessary.

    • SPI GPIO DIR reg configuration
      • GpioCtrlRegs.GPBDIR.bit.GPIOx = 1;
      • The STE, SIMO, and SPICLK pins should be configured as outputs pins.

    Very sorry again for the delay. I'll make sure it doesn't happen again.
    Jason Osborn

  • Hello,

     As per your suggestion I made changes in my code but still I cant read the data..

    I used the ADS1258EVM software and tried to read the CONFIG0 register. When I clicked the Read button, I captured the following images on the oscilloscope:

    1. On the DIN pin: the data sent is 0x40, 0x00 to read the CONFIG0 register (Yellow: MOSI, Green: SCLK)(see image_1)

    2. On the DOUT pin: the data read from the ADS1258 is 0x0A.(see image_2)

      And tell me one thing — finally, what should be the value of the CLKPOLARITY and CLK_PHASE bits?
  • In an earlier post, I stated that it looked to me like POL=0, PHASE=1 (rising edge with delay), based on the ADS1258 datasheet. Based on the waveforms provided, this still appears to be correct.

    None of the posts so far with your software have shown MISO/DOUT. Is anything showing up on MISO at all when you use it? If not, can you try other commands?

    As far as I can tell, the MOSI signal from your SW and the MOSI signal from the ADS1258EVM SW look the same. This makes me think that something else is going wrong.

    In your SW:

    • If you're not able to see any response on MISO from any commands, then I'm concerned that the board itself isn't properly powered-on, which is why I asked about the RESET pin earlier.
    • If you ARE able to see response on MISO, then we'll need to take another look at the SPI Rx implementation.

    Regards,
    Jason Osborn

  • I have attached the complete code that I am using. On the oscilloscope, I am not seeing any response on the MOSI pin — only blank data is visible. Please check and let me know what the issue might be.

    #include "F28x_Project.h"
    #include "ADS1258.h"
    
    static uint8_t registerMap[NUM_REGISTERS];
    uint8_t DataTx[2] = { 0 };
    uint8_t DataRx[2] = { 0 };
    uint8_t dataRx;
    
    void main(void)
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file
       InitSysCtrl();
    
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // Setup only the GPIO only for SPI-A functionality
    // This function is found in F2837xD_Spi.c
       InitSpiaGpio();
       InitADS1258Gpio();
    
    // Step 3. Clear all interrupts:
       DINT;
    
    // Initialize PIE control registers to their default state.
    // The default state is all PIE __interrupts disabled and flags are cleared.
    // This function is found in the F2837xD_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU __interrupts and clear all CPU __interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the __interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
       InitPieVectTable();
    
    // Step 4. Initialize the Device Peripherals:
       spi_fifo_init();     // Initialize the SPI FIFO
    
    // Step 5. User specific code:
       adcStartupRoutine();
    
       for(;;)
       {
           readSingleRegister(0X00);
           DELAY_US(50000);
       }
    }
    
    void adcStartupRoutine(void)
    {
        /* (OPTIONAL) Provide additional delay time for power supply settling */
        DELAY_US(50000);
    
        GpioDataRegs.GPBSET.bit.GPIO61 = 1;      // CS HIGH
    
        /* (REQUIRED) Set nRESET/nPWDN pin high for ADC operation */
        GpioDataRegs.GPBCLEAR.bit.GPIO52 = 1;    // PWDN low
        DELAY_US(100);
        GpioDataRegs.GPBSET.bit.GPIO52 = 1;      // PWDN high
        DELAY_US(10000);
    
        /* (REQUIRED) tWAKE delay */
        DELAY_US(5000);
    }
    
    uint8_t spiSendReceiveByte(uint8_t dataTx)
    {
       // Wait until the transmit buffer is empty
       while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG == 1);
    
       // Write data to the transmit buffer
       SpiaRegs.SPITXBUF =dataTx << 8;  // Upper byte used
    
       // Wait until data is received (RX ready)
       while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
    
       // Read received data (RXBUF is 16 bits, use upper 8 bits)
       uint8_t dataRx = (SpiaRegs.SPIRXBUF >> 8);
    
       return dataRx;
    }
    
    
    //void spiSendReceiveArrays(uint8_t DataTx[], uint8_t DataRx[], uint8_t byteLength)
    //{
    //    volatile uint16_t dummy;
    //
    //    /* Set the nCS pin LOW */
    //    GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1;   // CS LOW
    //   // DELAY_US(1);
    //
    //    uint8_t i;
    //    for (i = 0; i < byteLength; i++)
    //    {
    //        DataRx[i] = spiSendReceiveByte(DataTx[i]);
    //    }
    //
    //    DELAY_US(1);
    //    GpioDataRegs.GPBSET.bit.GPIO61 = 1; // CS HIGH
    //    DELAY_US(1);
    //}
    
    
    void spiSendReceiveArrays(uint8_t DataTx[], uint8_t DataRx[], uint8_t byteLength)
    {
        volatile uint16_t dummy;
    
        // Pull CS low to start transaction
        GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1;   // CS LOW
    
        // Clear RX FIFO before starting
        SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0;
        SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;
    
        uint8_t i;
        // Load all bytes into TX FIFO back-to-back
        for ( i = 0; i < byteLength; i++)
        {
            // Wait for space in TX FIFO
            while(SpiaRegs.SPIFFTX.bit.TXFFST >= 4);
    
            // Send the byte (upper 8 bits are used)
            SpiaRegs.SPITXBUF = DataTx[i] << 8;
        }
    
        // Wait until all bytes are shifted out
        while(SpiaRegs.SPIFFTX.bit.TXFFST != 0);
    
        // Wait until RX FIFO has all bytes
        while(SpiaRegs.SPIFFRX.bit.RXFFST < byteLength);
    
        // Read all received bytes
        for ( i = 0; i < byteLength; i++)
        {
            DataRx[i] = (uint8_t)(SpiaRegs.SPIRXBUF >> 8);
        }
    
        // Pull CS high to end transaction
        GpioDataRegs.GPBSET.bit.GPIO61 = 1; // CS HIGH
    }
    
    void spi_fifo_init()
    {
        //
        // Initialize SPI FIFO registers
        //
        SpiaRegs.SPIFFTX.all = 0xE040;
        SpiaRegs.SPIFFRX.all = 0x2044;
        SpiaRegs.SPIFFCT.all = 0x0;
    
        //
        // Initialize core SPI registers
        //
        InitSpi();
    }
    
    void InitADS1258Gpio(void)
    {
        EALLOW;
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0;   // GPIO80 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO52  = 1;   // Output (PWDN)
    
        GpioCtrlRegs.GPDMUX1.bit.GPIO97 = 0;   // GPIO84 as GPIO
        GpioCtrlRegs.GPDDIR.bit.GPIO97  = 1;   // Output (RESET)
    
        GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPCDIR.bit .GPIO67 = 1;   // Output (START)
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO61  = 1;   // Output (CS)
    
        GpioCtrlRegs.GPBDIR.bit.GPIO58 = 1; // SIMO out
        GpioCtrlRegs.GPBDIR.bit.GPIO60 = 1; // SCLK out
        GpioCtrlRegs.GPBDIR.bit.GPIO59 = 0; // SOMI in
    
        EDIS;
    }
    
    uint8_t readSingleRegister(uint8_t address)
    {
        /* Build TX array and send it */
        DataTx[0] = OPCODE_RREG | (address & OPCODE_A_MASK);
        DataTx[1] = 0x00; // dummy byte to clock out data
        spiSendReceiveArrays(DataTx, DataRx, 2);
    
        /* Update register array and return read result*/
        registerMap[address] = DataRx[1];
        return DataRx[1];
    }
    
    #include "F2837xD_device.h"
    #include "F2837xD_Examples.h"
    
    //
    // InitSPI - This function initializes the SPI to a known state
    //
    void InitSpi(void)
    {
        // Initialize SPI-A
    
        // Set reset low before configuration changes
        // Clock polarity (0 == rising, 1 == falling)
        // 16-bit character
        // Enable loop-back
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    
        SpiaRegs.SPIPRI.bit.TRIWIRE = 0;
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
        SpiaRegs.SPICCR.bit.SPICHAR = 7;
        SpiaRegs.SPICCR.bit.SPILBK = 0;
    
        // Enable master (0 == slave, 1 == master)
        // Enable transmission (Talk)
        // Clock phase (0 == normal, 1 == delayed)
        // SPI interrupts are disabled
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
        SpiaRegs.SPICTL.bit.TALK = 1;
        SpiaRegs.SPICTL.bit.CLK_PHASE = 1;
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;
    
        // Set the baud rate
        SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 24;
    
        // Set FREE bit
        // Halting on a breakpoint will not halt the SPI
        SpiaRegs.SPIPRI.bit.FREE = 1;
    
        // Release the SPI from reset
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;
    }
    
    void InitSpiGpio()
    {
       InitSpiaGpio();
    }
    
    //
    // InitSpiaGpio - Initialize SPIA GPIOs
    //
    void InitSpiaGpio()
    {
       EALLOW;
    
        //
        // Enable internal pull-up for the selected pins
        //
        // Pull-ups can be enabled or disabled by the user.
        // This will enable the pullups for the specified pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;  // Enable pull-up on GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;  // Enable pull-up on GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;  // Enable pull-up on GPIO18 (SPICLKA)
     //   GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0;  // Enable pull-up on GPIO19 (SPISTEA)
    
        //
        // Set qualification for selected pins to asynch only
        //
        // This will select asynch (no qualification) for the selected pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3; // Asynch input GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3; // Asynch input GPIO18 (SPICLKA)
      //  GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 3; // Asynch input GPIO19 (SPISTEA)
    
    
        GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
     //   GpioCtrlRegs.GPBGMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
        //
        //Configure SPI-A pins using GPIO regs
        //
        // This specifies which of the possible GPIO pins will be SPI functional
        // pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
     //   GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
    
        EDIS;
    }
    
    //
    // End of file
    //
    

  • I don't think the problem is related to the SPI, at this point. It seems more like a problem with the setup, like I suggested before. I believe your power-on process is not correct, particularly given you're seeing nothing on MISO.

    Please look at the following pins and compare the behavior of your code with the behavior of the ADS1258EVM GUI. Perform each of the following tests in order:

    1. ADC Clock (aka MCLK_OUT in the schematic)
    2. RESET
    3. PWDN
    4. SPI Clock and MOSI, setting your oscilloscope time scale to observe a single pulse on the MOSI pin.

    Corresponding debug activities:

    1. If you don't see anything on the ADC Clock (i.e. main system clock), then you need to set up a 16MHz clock source for the ADS1258.
      1. The simplest way to do this is to configure an unused ePWM at 16MHz and 50% duty cycle. See the ePWM examples and TRM section for details.
      2. If no ePWM signals are available in your end application, you can also use the APWM functionality of the eCAP peripheral or simply configure one of the CPU Timers to toggle a GPIO at the desired frequency.
    2. (see (3) )
    3. If RESET or PWDN is in an incorrect state, alter your configuration accordingly.
    4. If SPI Clock and DIN/MOSI relationship does not match, then I misinterpreted the SPI clock configuration due to the zoom level, apologies- set POL=0, PHASE=0.

    Regards,
    Jason Osborn

  • Hello,

    So, I have now generated an external 16 MHz clock and given it to the ADC_CLK pin of the ADS1258.
    I checked the waveforms of RESET, PWDN, MOSI, MISO,SCLK and CS on the oscilloscope and compared them with the waveforms tested on the ADS1258 EVM-PDK board, and they are correct. SCLK freq is 1MHz.

    Now, I can see data on the MISO pin/DOUT on the oscilloscope, but it is not 0x0A as expected. I have attached the oscilloscope image as well as the code.
    Based on the waveform comparison, the Clock Polarity = 0 and Clock Phase = 1.

    #include "F28x_Project.h"
    #include "ADS1258.h"
    
    uint8_t sdata;  // send data
    uint8_t rdata;  // received data
    int c;
    uint8_t config0,tmp;
    Uint16 received;
    uint8_t config0_value;
    static uint8_t registerMap[NUM_REGISTERS];
    static uint8_t registerMap1[NUM_REGISTERS];
    uint8_t initRegisterMap[NUM_REGISTERS];
    /* Initialize arrays */
    uint8_t DataTx[2] = { 0 };
    uint8_t DataRx[2] = { 0 };
    uint8_t regVal ;
    uint8_t dataRx;
    int count;
    int  EPWM1_TIMER_TBPRD,EPWM1_MAX_CMPA,EPWM1_MIN_CMPA,EPWM1_CMP_UP,EPWM1_CMP_DOWN;    // Period register
    
    void main(void)
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // Setup only the GPIO only for SPI-A functionality
    // This function is found in F2837xD_Spi.c
       InitSpiaGpio();
       InitADS1258Gpio();
    
       // Enable PWM1, PWM6
       CpuSysRegs.PCLKCR2.bit.EPWM1=1;
    
       // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
       // These functions are in the F2837xD_EPwm.c file
       InitEPwm1Gpio();
    
    // Step 3. Clear all interrupts:
       DINT;
    
    //
    // Initialize PIE control registers to their default state.
    // The default state is all PIE __interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xD_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU __interrupts and clear all CPU __interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the __interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
       InitPieVectTable();
    
    
        // Enable global Interrupts and higher priority real-time debug events:
        IER = M_INT1 |M_INT3 | M_INT8 ;                        // For ADCA0,EPWM1 and for SCIC_RX
    
    
        EPWM1_TIMER_TBPRD=2;  // Period register
        EPWM1_MAX_CMPA=1;
        EPWM1_MIN_CMPA=1;
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
        InitEPwm1Example();
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    
        //worktime start
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    
    // Step 4. Initialize the Device Peripherals:
       spi_fifo_init();     // Initialize the SPI FIFO
    
    // Step 5. User specific code:
       adcStartupRoutine();
    
       for(;;)
       {
           readSingleRegister(0x00);
           DELAY_US(10000);
    
       }
    }
    
    void adcStartupRoutine(void)
    {
        /* (OPTIONAL) Provide additional delay time for power supply settling */
        DELAY_US(50000);
    
        /* (REQUIRED) Set nRESET/nPWDN pin high for ADC operation */
        GpioDataRegs.GPBCLEAR.bit.GPIO52 = 1;  // PWDN low
        DELAY_US(100);
        GpioDataRegs.GPBSET.bit.GPIO52 = 1;    // PWDN high
        DELAY_US(10000);
    
        /* (REQUIRED) tWAKE delay */
        DELAY_US(5000);
    
        /* (OPTIONAL) Toggle nRESET pin to assure default register settings. */
        /* NOTE: This also ensures that the device registers are unlocked.   */
        GpioDataRegs.GPDCLEAR.bit.GPIO97 = 1;  // RESET low
        DELAY_US(1000);
        GpioDataRegs.GPDSET.bit.GPIO97 = 1;    // RESET high
        DELAY_US(3000);
    }
    
    
    uint8_t spiSendReceiveByte(uint8_t dataTx)
    {
        // Wait until the transmit buffer is empty
        while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG == 1);
    
        // Write data to the transmit buffer
        SpiaRegs.SPITXBUF =dataTx << 8;  // Upper byte used
    
    }
    
    void spiSendReceiveArrays(uint8_t DataTx[], uint8_t DataRx[], uint8_t byteLength)
    {
    
        /* Set the nCS pin LOW */
        GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1;   // CS LOW
    
        spiSendReceiveByte(DataTx[0]);
        spiSendReceiveByte(DataTx[1]);
    
        DELAY_US(10);
        GpioDataRegs.GPBSET.bit.GPIO61 = 1; // CS HIGH
        DELAY_US(10);
    }
    
    void spi_fifo_init()
    {
        //
        // Initialize SPI FIFO registers
        //
        SpiaRegs.SPIFFTX.all = 0xE040;
        SpiaRegs.SPIFFRX.all = 0x2044;
        SpiaRegs.SPIFFCT.all = 0x0;
    
        //
        // Initialize core SPI registers
        //
        InitSpi();
    }
    
    void InitADS1258Gpio(void)
    {
        EALLOW;
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0;  // GPIO80 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO52 = 1;   // Output (PWDN)
    
        GpioCtrlRegs.GPDMUX1.bit.GPIO97 = 0;  // GPIO84 as GPIO
        GpioCtrlRegs.GPDDIR.bit.GPIO97 = 1;   // Output (RESET)
    
        GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPCDIR.bit.GPIO67 = 1;    // Output (START)
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1;    // Output (CS)
    
        EDIS;
    
    }
    
    uint8_t readSingleRegister(uint8_t address)
    {
        /* Build TX array and send it */
        DataTx[0] = OPCODE_RREG | (address & OPCODE_A_MASK);
        spiSendReceiveArrays(DataTx, DataRx, 2);
    
        // Wait until data is received (RX ready)
     //     while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
     //
         // Read received data (RXBUF is 16 bits, use upper 8 bits)
    //     dataRx = (SpiaRegs.SPIRXBUF >> 8);
    }
    
    
    void InitEPwm1Example()
    {
       //
       // Setup TBCLK
       //
       EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
       EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD;       // Set timer period
       EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading
       EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;        // Phase is 0
       EPwm1Regs.TBCTR = 0x0000;                  // Clear counter
       EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
       EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
       //
       // Setup shadow register load on ZERO
       //
       EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
       EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
       EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
       //
       // Set Compare values
       //
       EPwm1Regs.CMPA.bit.CMPA = EPWM1_MIN_CMPA;     // Set compare A value
    
       //
       // Set actions
       //
       EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM1A on Zero
       EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM1A on event A,
    
       //
       // Interrupt where we will change the Compare Values
       //
       EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
       EPwm1Regs.ETSEL.bit.INTEN = 1;                // Enable INT
       EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 3rd event
    
    }
    
    #include "F28x_Project.h"
    #include "ADS1258.h"
    
    uint8_t sdata;  // send data
    uint8_t rdata;  // received data
    int c;
    uint8_t config0,tmp;
    Uint16 received;
    uint8_t config0_value;
    static uint8_t registerMap[NUM_REGISTERS];
    static uint8_t registerMap1[NUM_REGISTERS];
    uint8_t initRegisterMap[NUM_REGISTERS];
    /* Initialize arrays */
    uint8_t DataTx[2] = { 0 };
    uint8_t DataRx[2] = { 0 };
    uint8_t regVal ;
    uint8_t dataRx;
    int count;
    int  EPWM1_TIMER_TBPRD,EPWM1_MAX_CMPA,EPWM1_MIN_CMPA,EPWM1_CMP_UP,EPWM1_CMP_DOWN;    // Period register
    
    void main(void)
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // Setup only the GPIO only for SPI-A functionality
    // This function is found in F2837xD_Spi.c
       InitSpiaGpio();
       InitADS1258Gpio();
    
       // Enable PWM1, PWM6
       CpuSysRegs.PCLKCR2.bit.EPWM1=1;
    
       // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
       // These functions are in the F2837xD_EPwm.c file
       InitEPwm1Gpio();
    
    // Step 3. Clear all interrupts:
       DINT;
    
    //
    // Initialize PIE control registers to their default state.
    // The default state is all PIE __interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xD_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU __interrupts and clear all CPU __interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the __interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
       InitPieVectTable();
    
    
        // Enable global Interrupts and higher priority real-time debug events:
        IER = M_INT1 |M_INT3 | M_INT8 ;                        // For ADCA0,EPWM1 and for SCIC_RX
    
    
        EPWM1_TIMER_TBPRD=2;  // Period register
        EPWM1_MAX_CMPA=1;
        EPWM1_MIN_CMPA=1;
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
        InitEPwm1Example();
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    
        //worktime start
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    
    // Step 4. Initialize the Device Peripherals:
       spi_fifo_init();     // Initialize the SPI FIFO
    
    // Step 5. User specific code:
       adcStartupRoutine();
    
       for(;;)
       {
           readSingleRegister(0x00);
           DELAY_US(10000);
    
       }
    }
    
    void adcStartupRoutine(void)
    {
        /* (OPTIONAL) Provide additional delay time for power supply settling */
        DELAY_US(50000);
    
        /* (REQUIRED) Set nRESET/nPWDN pin high for ADC operation */
        GpioDataRegs.GPBCLEAR.bit.GPIO52 = 1;  // PWDN low
        DELAY_US(100);
        GpioDataRegs.GPBSET.bit.GPIO52 = 1;    // PWDN high
        DELAY_US(10000);
    
        /* (REQUIRED) tWAKE delay */
        DELAY_US(5000);
    
        /* (OPTIONAL) Toggle nRESET pin to assure default register settings. */
        /* NOTE: This also ensures that the device registers are unlocked.   */
        GpioDataRegs.GPDCLEAR.bit.GPIO97 = 1;  // RESET low
        DELAY_US(1000);
        GpioDataRegs.GPDSET.bit.GPIO97 = 1;    // RESET high
        DELAY_US(3000);
    }
    
    
    uint8_t spiSendReceiveByte(uint8_t dataTx)
    {
        // Wait until the transmit buffer is empty
        while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG == 1);
    
        // Write data to the transmit buffer
        SpiaRegs.SPITXBUF =dataTx << 8;  // Upper byte used
    
    }
    
    void spiSendReceiveArrays(uint8_t DataTx[], uint8_t DataRx[], uint8_t byteLength)
    {
    
        /* Set the nCS pin LOW */
        GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1;   // CS LOW
    
        spiSendReceiveByte(DataTx[0]);
        spiSendReceiveByte(DataTx[1]);
    
        DELAY_US(10);
        GpioDataRegs.GPBSET.bit.GPIO61 = 1; // CS HIGH
        DELAY_US(10);
    }
    
    void spi_fifo_init()
    {
        //
        // Initialize SPI FIFO registers
        //
        SpiaRegs.SPIFFTX.all = 0xE040;
        SpiaRegs.SPIFFRX.all = 0x2044;
        SpiaRegs.SPIFFCT.all = 0x0;
    
        //
        // Initialize core SPI registers
        //
        InitSpi();
    }
    
    void InitADS1258Gpio(void)
    {
        EALLOW;
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0;  // GPIO80 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO52 = 1;   // Output (PWDN)
    
        GpioCtrlRegs.GPDMUX1.bit.GPIO97 = 0;  // GPIO84 as GPIO
        GpioCtrlRegs.GPDDIR.bit.GPIO97 = 1;   // Output (RESET)
    
        GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPCDIR.bit.GPIO67 = 1;    // Output (START)
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1;    // Output (CS)
    
        EDIS;
    
    }
    
    uint8_t readSingleRegister(uint8_t address)
    {
        /* Build TX array and send it */
        DataTx[0] = OPCODE_RREG | (address & OPCODE_A_MASK);
        spiSendReceiveArrays(DataTx, DataRx, 2);
    
        // Wait until data is received (RX ready)
     //     while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
     //
         // Read received data (RXBUF is 16 bits, use upper 8 bits)
    //     dataRx = (SpiaRegs.SPIRXBUF >> 8);
    }
    
    
    void InitEPwm1Example()
    {
       //
       // Setup TBCLK
       //
       EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
       EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD;       // Set timer period
       EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading
       EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;        // Phase is 0
       EPwm1Regs.TBCTR = 0x0000;                  // Clear counter
       EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
       EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
       //
       // Setup shadow register load on ZERO
       //
       EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
       EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
       EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
       //
       // Set Compare values
       //
       EPwm1Regs.CMPA.bit.CMPA = EPWM1_MIN_CMPA;     // Set compare A value
    
       //
       // Set actions
       //
       EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM1A on Zero
       EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM1A on event A,
    
       //
       // Interrupt where we will change the Compare Values
       //
       EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
       EPwm1Regs.ETSEL.bit.INTEN = 1;                // Enable INT
       EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 3rd event
    
    }
    #include "F28x_Project.h"
    #include "ADS1258.h"
    
    uint8_t sdata;  // send data
    uint8_t rdata;  // received data
    int c;
    uint8_t config0,tmp;
    Uint16 received;
    uint8_t config0_value;
    static uint8_t registerMap[NUM_REGISTERS];
    static uint8_t registerMap1[NUM_REGISTERS];
    uint8_t initRegisterMap[NUM_REGISTERS];
    /* Initialize arrays */
    uint8_t DataTx[2] = { 0 };
    uint8_t DataRx[2] = { 0 };
    uint8_t regVal ;
    uint8_t dataRx;
    int count;
    int  EPWM1_TIMER_TBPRD,EPWM1_MAX_CMPA,EPWM1_MIN_CMPA,EPWM1_CMP_UP,EPWM1_CMP_DOWN;    // Period register
    
    void main(void)
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // Setup only the GPIO only for SPI-A functionality
    // This function is found in F2837xD_Spi.c
       InitSpiaGpio();
       InitADS1258Gpio();
    
       // Enable PWM1, PWM6
       CpuSysRegs.PCLKCR2.bit.EPWM1=1;
    
       // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
       // These functions are in the F2837xD_EPwm.c file
       InitEPwm1Gpio();
    
    // Step 3. Clear all interrupts:
       DINT;
    
    //
    // Initialize PIE control registers to their default state.
    // The default state is all PIE __interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xD_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU __interrupts and clear all CPU __interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the __interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
       InitPieVectTable();
    
    
        // Enable global Interrupts and higher priority real-time debug events:
        IER = M_INT1 |M_INT3 | M_INT8 ;                        // For ADCA0,EPWM1 and for SCIC_RX
    
    
        EPWM1_TIMER_TBPRD=2;  // Period register
        EPWM1_MAX_CMPA=1;
        EPWM1_MIN_CMPA=1;
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
        InitEPwm1Example();
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    
        //worktime start
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    
    // Step 4. Initialize the Device Peripherals:
       spi_fifo_init();     // Initialize the SPI FIFO
    
    // Step 5. User specific code:
       adcStartupRoutine();
    
       for(;;)
       {
           readSingleRegister(0x00);
           DELAY_US(10000);
    
       }
    }
    
    void adcStartupRoutine(void)
    {
        /* (OPTIONAL) Provide additional delay time for power supply settling */
        DELAY_US(50000);
    
        /* (REQUIRED) Set nRESET/nPWDN pin high for ADC operation */
        GpioDataRegs.GPBCLEAR.bit.GPIO52 = 1;  // PWDN low
        DELAY_US(100);
        GpioDataRegs.GPBSET.bit.GPIO52 = 1;    // PWDN high
        DELAY_US(10000);
    
        /* (REQUIRED) tWAKE delay */
        DELAY_US(5000);
    
        /* (OPTIONAL) Toggle nRESET pin to assure default register settings. */
        /* NOTE: This also ensures that the device registers are unlocked.   */
        GpioDataRegs.GPDCLEAR.bit.GPIO97 = 1;  // RESET low
        DELAY_US(1000);
        GpioDataRegs.GPDSET.bit.GPIO97 = 1;    // RESET high
        DELAY_US(3000);
    }
    
    
    uint8_t spiSendReceiveByte(uint8_t dataTx)
    {
        // Wait until the transmit buffer is empty
        while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG == 1);
    
        // Write data to the transmit buffer
        SpiaRegs.SPITXBUF =dataTx << 8;  // Upper byte used
    
    }
    
    void spiSendReceiveArrays(uint8_t DataTx[], uint8_t DataRx[], uint8_t byteLength)
    {
    
        /* Set the nCS pin LOW */
        GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1;   // CS LOW
    
        spiSendReceiveByte(DataTx[0]);
        spiSendReceiveByte(DataTx[1]);
    
        DELAY_US(10);
        GpioDataRegs.GPBSET.bit.GPIO61 = 1; // CS HIGH
        DELAY_US(10);
    }
    
    void spi_fifo_init()
    {
        //
        // Initialize SPI FIFO registers
        //
        SpiaRegs.SPIFFTX.all = 0xE040;
        SpiaRegs.SPIFFRX.all = 0x2044;
        SpiaRegs.SPIFFCT.all = 0x0;
    
        //
        // Initialize core SPI registers
        //
        InitSpi();
    }
    
    void InitADS1258Gpio(void)
    {
        EALLOW;
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0;  // GPIO80 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO52 = 1;   // Output (PWDN)
    
        GpioCtrlRegs.GPDMUX1.bit.GPIO97 = 0;  // GPIO84 as GPIO
        GpioCtrlRegs.GPDDIR.bit.GPIO97 = 1;   // Output (RESET)
    
        GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPCDIR.bit.GPIO67 = 1;    // Output (START)
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1;    // Output (CS)
    
        EDIS;
    
    }
    
    uint8_t readSingleRegister(uint8_t address)
    {
        /* Build TX array and send it */
        DataTx[0] = OPCODE_RREG | (address & OPCODE_A_MASK);
        spiSendReceiveArrays(DataTx, DataRx, 2);
    
        // Wait until data is received (RX ready)
     //     while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
     //
         // Read received data (RXBUF is 16 bits, use upper 8 bits)
    //     dataRx = (SpiaRegs.SPIRXBUF >> 8);
    }
    
    
    void InitEPwm1Example()
    {
       //
       // Setup TBCLK
       //
       EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
       EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD;       // Set timer period
       EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading
       EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;        // Phase is 0
       EPwm1Regs.TBCTR = 0x0000;                  // Clear counter
       EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
       EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
       //
       // Setup shadow register load on ZERO
       //
       EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
       EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
       EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
       //
       // Set Compare values
       //
       EPwm1Regs.CMPA.bit.CMPA = EPWM1_MIN_CMPA;     // Set compare A value
    
       //
       // Set actions
       //
       EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM1A on Zero
       EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM1A on event A,
    
       //
       // Interrupt where we will change the Compare Values
       //
       EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
       EPwm1Regs.ETSEL.bit.INTEN = 1;                // Enable INT
       EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 3rd event
    
    }
    void InitSpi(void)
    {
        // Initialize SPI-A
    
        // Set reset low before configuration changes
        // Clock polarity (0 == rising, 1 == falling)
        // 16-bit character
        // Enable loop-back
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    
        SpiaRegs.SPIPRI.bit.TRIWIRE = 0;
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
        SpiaRegs.SPICCR.bit.SPICHAR = 7;
        SpiaRegs.SPICCR.bit.SPILBK = 0;
    
        // Enable master (0 == slave, 1 == master)
        // Enable transmission (Talk)
        // Clock phase (0 == normal, 1 == delayed)
        // SPI interrupts are disabled
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
        SpiaRegs.SPICTL.bit.TALK = 1;
        SpiaRegs.SPICTL.bit.CLK_PHASE = 1;
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;
    
        // Set the baud rate
        SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 24;
    
        // Set FREE bit
        // Halting on a breakpoint will not halt the SPI
        SpiaRegs.SPIPRI.bit.FREE = 1;
    
        // Release the SPI from reset
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;
    }
    
    void InitSpiGpio()
    {
       InitSpiaGpio();
    }
    
    //
    // InitSpiaGpio - Initialize SPIA GPIOs
    //
    void InitSpiaGpio()
    {
       EALLOW;
    
        //
        // Enable internal pull-up for the selected pins
        //
        // Pull-ups can be enabled or disabled by the user.
        // This will enable the pullups for the specified pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;  // Enable pull-up on GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;  // Enable pull-up on GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;  // Enable pull-up on GPIO18 (SPICLKA)
     //   GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0;  // Enable pull-up on GPIO19 (SPISTEA)
    
        //
        // Set qualification for selected pins to asynch only
        //
        // This will select asynch (no qualification) for the selected pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3; // Asynch input GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3; // Asynch input GPIO18 (SPICLKA)
      //  GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 3; // Asynch input GPIO19 (SPISTEA)
    
    
        GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
     //   GpioCtrlRegs.GPBGMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
        //
        //Configure SPI-A pins using GPIO regs
        //
        // This specifies which of the possible GPIO pins will be SPI functional
        // pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
     //   GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
    
        EDIS;
    }
    
    

  • The hex value of the data you're seeing there is 0x8E0A (data is latched on the rising edge with this clk configuration). Per figure 58 of the ads1258 datasheet, you should discard the first byte of data coming out of the device- MISO is not meaningful until after the command byte has concluded.

    You are seeing a correct value here.

    Regards,
    Jason Osborn

  • Okay.. Now, I can read register values. I want to read the voltage applied on Ain0 pin. 

    I used the ADS1258 EVM software to verify the ADC output values for known input voltages and prepared an Excel table as shown below. Could you please check if the formulae I used are correct?

    Now, instead of the PGA/EVM board, I have interfaced the ADS1258 with a TMS320F28379D controller. When I apply 0 V at AIN0, the oscilloscope shows that the hex code read is 0x9595EFCECF. Considering only the last 3 bytes (0xEFCECF), the calculated voltage is 0.316  and expected should be close to −2.24 V, but I am not getting the expected result. I have also attached my code. Can you please review and tell me what exactly might be wrong?

    Input Voltage Hex (24-bit) Unsigned (dec) Signed (dec) Formula used VINV_{IN} (V) Actual AIN0 (V)
    3.3 V 0x26054B 2,491,723 +2,491,723 IN = (Code / 2^23) × VREF 0.7426 0.7426 + VREF
    0 V (GND) 0x8CFABD 9,239,229 9,239,229 − 16,777,216 = −7,537,987 If u ≥ 2^23 → s = u − 2^24, then IN = (s / 2^23) × VREF −2.2465 −2.2465 + VREF

     "F28x_Project.h"
    #include "ADS1258.h"
    
    /* Initialize arrays */
    uint8_t DataTx[5] = { 0 };
    uint8_t DataRx[5] = { 0 };
    uint8_t regVal ;
    uint8_t data[];
    uint8_t dataRx,dataPosition,byteLength;
    int count;
    int  EPWM1_TIMER_TBPRD,EPWM1_MAX_CMPA,EPWM1_MIN_CMPA,EPWM1_CMP_UP,EPWM1_CMP_DOWN;    // Period register
    static uint8_t registerMap[NUM_REGISTERS];
    int i;
    int32_t dataValues[5];
    uint8_t writeValues[7], statusBytes[5];
    int32_t upperByte,middleByte,lowerByte;
    void main(void)
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
    
        InitSysCtrl();
    
    
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // Setup only the GPIO only for SPI-A functionality
    // This function is found in F2837xD_Spi.c
       InitSpiaGpio();
       InitADS1258Gpio();
    
       // Enable PWM1, PWM6
       CpuSysRegs.PCLKCR2.bit.EPWM1=1;
    
       // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
       // These functions are in the F2837xD_EPwm.c file
       InitEPwm1Gpio();
    
    // Step 3. Clear all interrupts:
       DINT;
    
    //
    // Initialize PIE control registers to their default state.
    // The default state is all PIE __interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xD_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU __interrupts and clear all CPU __interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the __interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
       InitPieVectTable();
    
    
        // Enable global Interrupts and higher priority real-time debug events:
        IER = M_INT1 |M_INT3 | M_INT8 ;                        // For ADCA0,EPWM1 and for SCIC_RX
    
    
        EPWM1_TIMER_TBPRD=2;  // Period register
        EPWM1_MAX_CMPA=1;
        EPWM1_MIN_CMPA=1;
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
        InitEPwm1Example();
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    
        //worktime start
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    
    // Step 4. Initialize the Device Peripherals:
       spi_fifo_init();     // Initialize the SPI FIFO
    
    // Step 5. User specific code:
       adcStartupRoutine();
    
       for(;;)
       {
         readSingleRegister(0x02);
         DELAY_US(10000);
         DELAY_US(10000);
         DELAY_US(10000);
    
           // Wait and check that /DRDY interrupt occurred
           // b_pass &= waitForDRDYinterrupt(10);
           //  Read data in read direct mode
           dataValues[i] = readData(&statusBytes[i], NULL, DIRECT);
    
           DELAY_US(10000);
       }
    }
    
    void adcStartupRoutine(void)
    {
        /* (OPTIONAL) Provide additional delay time for power supply settling */
        DELAY_US(50000);
    
        /* (REQUIRED) Set nRESET/nPWDN pin high for ADC operation */
        GpioDataRegs.GPBCLEAR.bit.GPIO52 = 1;  // PWDN low
        DELAY_US(100);
        GpioDataRegs.GPBSET.bit.GPIO52 = 1;    // PWDN high
        DELAY_US(10000);
    
        /* (REQUIRED) tWAKE delay */
        DELAY_US(5000);
    
        /* (OPTIONAL) Toggle nRESET pin to assure default register settings. */
        /* NOTE: This also ensures that the device registers are unlocked.   */
        GpioDataRegs.GPDCLEAR.bit.GPIO97 = 1;  // RESET low
        DELAY_US(1000);
        GpioDataRegs.GPDSET.bit.GPIO97 = 1;    // RESET high
        DELAY_US(3000);
    
        GpioDataRegs.GPCSET.bit.GPIO67 = 1;    // START high
    }
    
    
    uint8_t spiSendReceiveByte(uint8_t dataTx)
    {
        // Wait until the transmit buffer is empty
        while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG == 1);
    
        // Write data to the transmit buffer
        SpiaRegs.SPITXBUF =dataTx << 8;  // Upper byte used
    
        dataRx = SpiaRegs.SPIRXBUF << 8;
    }
    
    uint8_t spiSendReceiveByte1(uint8_t dataTx)
    {
        // Wait until the transmit buffer is empty
        while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG == 1);
    
        // Write data to the transmit buffer
        SpiaRegs.SPITXBUF =dataTx << 8;  // Upper byte used
    
        dataRx = SpiaRegs.SPIRXBUF << 8;
    
        return dataRx;
    }
    
    void spiSendReceiveArrays(uint8_t DataTx[], uint8_t DataRx[], uint8_t byteLength)
    {
        /* Set the nCS pin LOW */
        GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1;   // CS LOW
    
        spiSendReceiveByte(DataTx[0]);
        spiSendReceiveByte(DataTx[1]);
    
        DELAY_US(10);
        GpioDataRegs.GPBSET.bit.GPIO61 = 1; // CS HIGH
    }
    
    void spiSendReceiveArrays1(uint8_t DataTx[], uint8_t DataRx[], uint8_t byteLength)
    {
        /* Set the nCS pin LOW */
        GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1; //CS LOW
    
        for (i = 0; i < 5; i++)
        {
            DataRx[i] = spiSendReceiveByte1(DataTx[i]);
        }
    
        DELAY_US(1000);
        GpioDataRegs.GPBSET.bit.GPIO61 = 1;  //CS HIGH
    }
    
    void spi_fifo_init()
    {
        //
        // Initialize SPI FIFO registers
        //
        SpiaRegs.SPIFFTX.all = 0xE040;
        SpiaRegs.SPIFFRX.all = 0x2044;
        SpiaRegs.SPIFFCT.all = 0x0;
    
        //
        // Initialize core SPI registers
        //
        InitSpi();
    }
    
    void InitADS1258Gpio(void)
    {
        EALLOW;
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0;  // GPIO80 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO52 = 1;   // Output (PWDN)
    
        GpioCtrlRegs.GPDMUX1.bit.GPIO97 = 0;  // GPIO84 as GPIO
        GpioCtrlRegs.GPDDIR.bit.GPIO97 = 1;   // Output (RESET)
    
        GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPCDIR.bit.GPIO67 = 1;    // Output (START)
    
        GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;   // GPIO4 as GPIO
        GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1;    // Output (CS)
    
        GPIO_SetupPinMux(22, GPIO_MUX_CPU1, 0);   // GPIO22 as GPIO
        GPIO_SetupPinOptions(22, GPIO_INPUT, 0);  // Input, no pullup/down
    
        EDIS;
    
    }
    
    uint8_t readSingleRegister(uint8_t address)
    {
        /* Build TX array and send it */
        DataTx[0] = OPCODE_RREG | (address & OPCODE_A_MASK);
        spiSendReceiveArrays(DataTx, DataRx, 2);
    }
    
    
    void InitEPwm1Example()
    {
       //
       // Setup TBCLK
       //
       EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
       EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD;       // Set timer period
       EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading
       EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;        // Phase is 0
       EPwm1Regs.TBCTR = 0x0000;                  // Clear counter
       EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
       EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
       //
       // Setup shadow register load on ZERO
       //
       EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
       EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
       EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
       //
       // Set Compare values
       //
       EPwm1Regs.CMPA.bit.CMPA = EPWM1_MIN_CMPA;     // Set compare A value
    
       //
       // Set actions
       //
       EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM1A on Zero
       EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM1A on event A,
    
       //
       // Interrupt where we will change the Compare Values
       //
       EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
       EPwm1Regs.ETSEL.bit.INTEN = 1;                // Enable INT
       EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 3rd event
    
    }
    
    int32_t readData(uint8_t status[], uint8_t data[], readMode mode)
    {
    
            DataTx[0] = OPCODE_READ_COMMAND | OPCODE_MUL_MASK;
           dataPosition = 2;
           byteLength=5;
             spiSendReceiveArrays1(DataTx, DataRx, byteLength);
    
            data[0] = DataRx[dataPosition + 0];
            data[1] = DataRx[dataPosition + 1];
            data[2] = DataRx[dataPosition + 2];
    
        int32_t signByte;
        if (DataRx[dataPosition] & 0x80u) { signByte = 0xFF000000; }
        else                              { signByte = 0x00000000; }
    
         upperByte   = ((int32_t) DataRx[dataPosition + 0] & 0xFF) << 16;
        middleByte  = ((int32_t) DataRx[dataPosition + 1] & 0xFF) << 8;
        lowerByte   = ((int32_t) DataRx[dataPosition + 2] & 0xFF) << 0;
    
        return (signByte | upperByte | middleByte | lowerByte);
    }
    
    uint8_t getRegisterValue(uint8_t address)
    {
        assert(address < NUM_REGISTERS);
        return registerMap[address];
    }
    void InitSpi(void)
    {
        // Initialize SPI-A
    
        // Set reset low before configuration changes
        // Clock polarity (0 == rising, 1 == falling)
        // 16-bit character
        // Enable loop-back
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    
        SpiaRegs.SPIPRI.bit.TRIWIRE = 0;
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
        SpiaRegs.SPICCR.bit.SPICHAR = 7;
        SpiaRegs.SPICCR.bit.SPILBK = 0;
    
        // Enable master (0 == slave, 1 == master)
        // Enable transmission (Talk)
        // Clock phase (0 == normal, 1 == delayed)
        // SPI interrupts are disabled
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
        SpiaRegs.SPICTL.bit.TALK = 1;
        SpiaRegs.SPICTL.bit.CLK_PHASE = 1;
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;
    
        // Set the baud rate
        SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 24;
    
        // Set FREE bit
        // Halting on a breakpoint will not halt the SPI
        SpiaRegs.SPIPRI.bit.FREE = 1;
    
        // Release the SPI from reset
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;
    }
    
    void InitSpiGpio()
    {
       InitSpiaGpio();
    }
    
    //
    // InitSpiaGpio - Initialize SPIA GPIOs
    //
    void InitSpiaGpio()
    {
       EALLOW;
    
        //
        // Enable internal pull-up for the selected pins
        //
        // Pull-ups can be enabled or disabled by the user.
        // This will enable the pullups for the specified pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;  // Enable pull-up on GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;  // Enable pull-up on GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;  // Enable pull-up on GPIO18 (SPICLKA)
     //   GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0;  // Enable pull-up on GPIO19 (SPISTEA)
    
        //
        // Set qualification for selected pins to asynch only
        //
        // This will select asynch (no qualification) for the selected pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO16 (SPISIMOA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3; // Asynch input GPIO17 (SPISOMIA)
        GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3; // Asynch input GPIO18 (SPICLKA)
      //  GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 3; // Asynch input GPIO19 (SPISTEA)
    
    
        GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
     //   GpioCtrlRegs.GPBGMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
        //
        //Configure SPI-A pins using GPIO regs
        //
        // This specifies which of the possible GPIO pins will be SPI functional
        // pins.
        // Comment out other unwanted lines.
        //
        GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3; // Configure GPIO16 as SPISIMOA
        GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3; // Configure GPIO17 as SPISOMIA
        GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3; // Configure GPIO18 as SPICLKA
     //   GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA
    
        EDIS;
    }
    

  • I'd suggest making a new thread for this issue, as it's distinct from the SPI issue you were seeing before. This will allow you to get the correct expert assigned to it.

    Regards,
    Jason Osborn