This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SSI between ADS1234 and TM4C123GH6PMI

Other Parts Discussed in Thread: ADS1234, ADS1115

Hello,

I have a Tiva C Series LaunchPad and an ADS1234 _ 24 bit converter.

I try to read the value of conversion on putty terminal by the SSI0 module of TM4C123GH6PMI uC.

I think that the mistake is on initialization of the transmit buffer, and on the method to read the value of conversion.

// SSI between ADS1234 and Tiva C Series LaunchPad

//*****************************************************************************

#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/ssi.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"

//*****************************************************************************
// Number of bytes to send and receive.
//
#define NUM_SSI_DATA            3

//*****************************************************************************
// This function sets up UART0 to be used for a console to display conversion
//
void InitConsole(void)
{
    // Enable GPIO port A which is used for UART0 pins.
   SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Configure the pin muxing for UART0 functions on port A0 and A1.
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);

    //
    // Enable UART0 so that we can configure the clock.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    // Use the internal 16MHz oscillator as the UART clock source.
    //
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

    // Select the alternate (UART) function for these pins.
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    // Initialize the UART for console I/O.
    UARTStdioConfig(0, 115200, 16000000);
}

//*****************************************************************************
//
// Configure SSI0 in master Freescale (SPI) mode.  This example will send out
// 3 bytes of data, then wait for 3 bytes of data to come in.  This will all be
// done using the polling method.
//
//*****************************************************************************
int
main(void)
{
    uint32_t pui32DataTx[NUM_SSI_DATA];
    uint32_t pui32DataRx[NUM_SSI_DATA];
    uint32_t ui32Index;

    //
    // Set the clocking to run directly from the external crystal/oscillator.
    SysCtlClockSet(SYSCTL_SYSDIV_2 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    //
    // Set up the serial console to use for displaying messages.  This is
    // just for this example program and is not needed for SSI operation.
    //
    InitConsole();

    //
    // Display the setup on the console.
    //
    UARTprintf("SSI ->\n");
    UARTprintf("  Mode: SPI\n");
    UARTprintf("  Data: 8-bit\n\n");

    //
    // The SSI0 peripheral must be enabled for use.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);

    //
    // For this example SSI0 is used with PortA[5:2].  The actual port and pins
    // used may be different on your part, consult the data sheet for more
    // information.  GPIO port A needs to be enabled so these pins can be used.
    // TODO: change this to whichever GPIO port you are using.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Configure the pin muxing for SSI0 functions on port A2, A3, A4, and A5.
    // This step is not necessary if your part does not support pin muxing.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinConfigure(GPIO_PA2_SSI0CLK);
    GPIOPinConfigure(GPIO_PA3_SSI0FSS);
    GPIOPinConfigure(GPIO_PA4_SSI0RX);
    GPIOPinConfigure(GPIO_PA5_SSI0TX);

    //
    // Configure the GPIO settings for the SSI pins.  This function also gives
    // control of these pins to the SSI hardware.  Consult the data sheet to
    // see which functions are allocated per pin.
    // The pins are assigned as follows:
    //      PA5 - SSI0Tx
    //      PA4 - SSI0Rx
    //      PA3 - SSI0Fss
    //      PA2 - SSI0CLK
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2);

    //
    // Configure and enable the SSI port for SPI master mode.  Use SSI0,
    // system clock supply, idle clock level low and active low clock in
    // freescale SPI mode, master mode, 1MHz SSI frequency, and 8-bit data.
    // For SPI mode, you can set the polarity of the SSI clock when the SSI
    // unit is idle.  You can also configure what clock edge you want to
    // capture data on.  Please reference the datasheet for more information on
    // the different SPI modes.
    //
    SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_1, SSI_MODE_MASTER, 5000000, 8);

    //
    // Enable the SSI0 module.
    //
    SSIEnable(SSI0_BASE);

    // Read any residual data from the SSI port.  This makes sure the receive
    // FIFOs are empty, so we don't read any unwanted junk.  This is done here
    // because the SPI SSI mode is full-duplex, which allows you to send and
    // receive at the same time.  The SSIDataGetNonBlocking function returns
    // "true" when data was returned, and "false" when no data was returned.
    // The "non-blocking" function checks if there is any data in the receive
    // FIFO and does not "hang" if there isn't.
    //
    while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx[0]))
    {
    }

    // Initialize the data to send.
    //
    pui32DataTx[0] = SysCtlClockGet();
    pui32DataTx[1] = SysCtlClockGet();
    pui32DataTx[2] = SysCtlClockGet();

    // Display indication that the SSI is transmitting data.
    //
    UARTprintf("Sent:\n  ");

    //
    // Send 3 bytes of data.
    //
    for(ui32Index = 0; ui32Index < NUM_SSI_DATA; ui32Index++)
    {
        //
        // Display the data that SSI is transferring.
        //
        UARTprintf("'%c' ", pui32DataTx[ui32Index]);

        //
        // Send the data using the "blocking" put function.  This function
        // will wait until there is room in the send FIFO before returning.
        // This allows you to assure that all the data you send makes it into
        // the send FIFO.
        //
        SSIDataPut(SSI0_BASE, pui32DataTx[ui32Index]);
    }

    //
    // Wait until SSI0 is done transferring all the data in the transmit FIFO.
    //
    while(SSIBusy(SSI0_BASE))
    {
    }

    //
    // Display indication that the SSI is receiving data.
    //
    UARTprintf("\nReceived:\n  ");

    //
    // Receive 3 bytes of data.
    //
    for(ui32Index = 0; ui32Index < NUM_SSI_DATA; ui32Index++)
    {
        //
        // Receive the data using the "blocking" Get function. This function
        // will wait until there is data in the receive FIFO before returning.
        //
    	if (ui32Index = 1)
    	{
        SSIDataGet(SSI0_BASE, &pui32DataRx[1]);

        // Since we are using 8-bit data, mask off the MSB.
        //
        pui32DataRx[1] &= 0x00FF;
    	}
    	else if (ui32Index = 2)
    	{
    		SSIDataGet(SSI0_BASE, &pui32DataRx[2]);
    		pui32DataRx[2] &= 0x00FF;
    	}
    	else
    	{
    		SSIDataGet(SSI0_BASE, &pui32DataRx[3]);
    		pui32DataRx[3] &= 0x00FF;

    	}

        //
        // Display the data that SSI0 received.
        //
        UARTprintf("'%c'", pui32DataRx[0] << pui32DataRx[1] << pui32DataRx[2]);
    }

    //
    // Return no errors
    //
    return(0);
}

Thanks,

Regards,

Antonino Proto

 

  • Hello Antonino,

    This looks pretty suspicious to me. Also can you check the same on the scope?

    UARTprintf("'%c'", pui32DataRx[0] << pui32DataRx[1] << pui32DataRx[2]);

    Also the conversion time is 12.5ms to 100ms depending on the speed of conversion as per the ADS1234 specification. Are you sure that you are waiting that long?

    I am not sure what the end application is but I would suggest using ADS1115 which has a simpler I2C interface.

    Regards

    Amit

  • Hello Amit,

    Conversion time is setted on 12,5ms.

    My application is convert an analog signal at the output of a load cell for force measuring.

    The ADS1234 is an ADC 24 bit converter.

    UARTprintf("'%c'", pui32DataRx[0] << pui32DataRx[1] << pui32DataRx[2]); is the the row code to read the value formed by three bytes.

    Is it correct? The MSB is on the pui32DataRx[0].

    Moreover, it is proper initialization of the three transmit buffers?

    Thanks a lot,

    Regards,

    Antonino

  • Hello Antonino,

    Since there is no Transmit from the TM4C123 connected to the ADS1234, the Transmit buffers do not matter. In fact to be safe, you can writ "0" to the transmit buffer.

    When reading the data, as far I have done and seen, it should be

    UARTprintf("'%x'", (pui32DataRx[2] | (pui32DataRx[1] << 8) | (pui32DataRx[0] <<16));

    as the data is arriving in the lower byte and is 24 bits and hence will overload the "%c"

    Regards

    Amit