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.

TMS320F28379D: How to work with 24 bits world SPI

Part Number: TMS320F28379D
Other Parts Discussed in Thread: ADS1298R, C2000WARE

Hi,

I'm trying to understand how could I use the SPI to communicate with a slave SPI peripherical that sends me 9 words of 24 bits. I started using one of the examples provides that uses the Driver lib, and reading the datasheet I found that the SPI buffer and fifos are 16 bits width. I thought that I could setup de SPI to 8 bit word and, then read byte to byte, but the API says, and as I see, the buffer reads the last significant byte only and "losses" the others, is it right? How could I proceed?

Best Regards,

Matheus Alexandre

  • Hi Matheus Alexandre,

    The SPICHAR field in SPICCR register determines the length of the character to be transmitted. You can set it to 8 for your case. This can be controlled via the SPI_setConfig API. In the example provided, it is set to 16 and hence configured for character length of 16.  Have you tried changing it? If not, can you give it a try?

    Regards,
    Praveen

  • Hi, Praveen

    Thank you, but I've already did that. The only way that I have to test right now is using the spi as slaver, but I think It shouldn't change the behavior expected. I'm sending from another SPI master (10 Mhz, POL 0 PHA 0), two words 24 bits width, 0x78ABCD and 0x123456. I'm using breakpoint at sData++, and at first pause I see 0x00000178 at rData, at the second pause I see 0x0000345E, then I resend the same data from the master and see at the third pause 0x00005E78 and at fourth pause 0x00003456.

    #include "driverlib.h"
    #include "device.h"
    
    //
    // Number of times the loop runs (Increase it if needed)
    //
    uint16_t LOOP_COUNT = 100;
    
    //
    // Function Prototypes
    //
    void initSPI(void);
    
    void initSPI_GPIO(void);
    
    //
    // Main
    //
    void main(void)
    {
        uint16_t sData = 2;                  // Send data
        uint32_t rData = 0;                  // Receive data
    
        uint32_t i = 0;
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pullups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Set up SPI, initializing it for FIFO mode
        //
        initSPI();
    
        initSPI_GPIO();
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Loop forever. Suspend or place breakpoints to observe the buffers.
        //
        while(1)
        {
    
            rData = SPI_readDataBlockingNonFIFO (SPIB_BASE);
    
            sData++;
    
            Example_PassCount++;
    
            for (i=0; i<2000000; i++)
            {
    
            }
        }
    }
    
    void initSPI()
    {
        SPI_disableModule(SPIB_BASE);
    
        SPI_setConfig(SPIB_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
                      SPI_MODE_SLAVE, 10000000, 8);
        SPI_setEmulationMode(SPIB_BASE, SPI_EMULATION_FREE_RUN);
    
        SPI_enableModule(SPIB_BASE);
    }
    
    void initSPI_GPIO()
    {
        EALLOW;
    
        //SPI B CONFIG
    
        GPIO_setPadConfig(63, GPIO_PIN_TYPE_PULLUP);
        GPIO_setPadConfig(64, GPIO_PIN_TYPE_PULLUP);
        GPIO_setPadConfig(65, GPIO_PIN_TYPE_PULLUP);
        GPIO_setPadConfig(66, GPIO_PIN_TYPE_PULLUP);
    
        GPIO_setDirectionMode(63, GPIO_DIR_MODE_IN);
        GPIO_setDirectionMode(64, GPIO_DIR_MODE_OUT);
        GPIO_setDirectionMode(65, GPIO_DIR_MODE_IN);
        GPIO_setDirectionMode(66, GPIO_DIR_MODE_IN);
    
        GPIO_setQualificationMode(63, GPIO_QUAL_ASYNC);
        GPIO_setQualificationMode(64, GPIO_QUAL_ASYNC);
        GPIO_setQualificationMode(65, GPIO_QUAL_ASYNC);
        GPIO_setQualificationMode(66, GPIO_QUAL_ASYNC);
    
        GPIO_setPinConfig (GPIO_63_SPISIMOB);
        GPIO_setPinConfig (GPIO_64_SPISOMIB);
        GPIO_setPinConfig (GPIO_65_SPICLKB);
        GPIO_setPinConfig (GPIO_66_SPISTEB);
    
        EDIS;
    }
    

  • You may want to consider using McBSP. Here is a link to a tutorial...http://www.add.ece.ufl.edu/4511/references/McBSP%20Tutorial.pdf

  • Hi Matheus,

    What are you using as a master device and what is the clock speed configured? Please be advised that the C2000 Device does not necessarily align with other "MODEs" as defined for other devices. The Phase and Polarity bits mean different things. Please refer to the user guides to determine what your transmit and receive edges are, and compare them with your master chip. Do not just match PHASE = 0 and Polarity = 0 and assume the MODE is the same. Refer to the SPI Clocking Schemes section in the TRM.

    Regards,

    Praveen

  • Thank you for the suggestion. I gonna try this module and I come back with the results.

  • Praveen, I used protocol analyzer from Analog discovery 2, and the clock seep configured at f28379d is DEVICE_SYSCLK_FREQ = 200 MHz, DEVICE_LSPCLK_FREQ = 50 MHz and SPI frequency 10 MHz . I'm sure that the frequency, POL and PHA of Analog discovery is well configured because I've already used it before. I gonna try to use mcBSP module as suggested by Todd, don't seens to be too dificulty.

    Sorry for double post, I forgot to respond to Praveen.

  • Hi Matheus,

    Did you get a chance to try it?

    Regards,

    Praveen

  • Hi, Praveen

    Sorry for the delay, I'm working in 2 different projects.

    I think I got it, I'm using spi's fifo enable, without interruption. I couldn't test the MISO yet.

    I still have some doubts about the spi:

    1) Do I need to use interruption when using spi's fifo?

    2) Do 8 bits word SPI works when fifo is enable? Because as I see on my programm it only start to transmite when the buffer gets 16 bits, even when I change to 8 bits word SPI config.

    3) I'm no used to work with fifo. As I understand, there are no instruction to fill the fifo and other instruction to start the spi transfer, are there?

    Besides the lib files from drive lib example, there are 3 files, the first one contains the main, spi_ads.c contains everything related to SPI and the spi_ads.h contains macros.

    My final target is communicate with ADS1298R ECFE.

    #include "driverlib.h"
    #include "device.h"
    #include "spi_ads.h"
    
    // Main
    void main(void)
    {
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pullups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Set up SPI, initializing it for FIFO mode
        //
        init_spi_ads();
        ads_reset();
    
        //Interrupt_enable(INT_SPIB_TX);
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Loop forever. Suspend or place breakpoints to observe the buffers.
        //
         while(1)
        {
        }
    }

    #include "spi_ads.h"
    
    void init_spi_ads()
    {
        EALLOW;
    
        //SPI B CONFIG
    
        GPIO_setPadConfig(SPI_MOSI, GPIO_PIN_TYPE_PULLUP);
        GPIO_setPadConfig(SPI_MISO, GPIO_PIN_TYPE_PULLUP);
        GPIO_setPadConfig(SPI_CLK, GPIO_PIN_TYPE_PULLUP);
        GPIO_setPadConfig(SPI_CS_1, GPIO_PIN_TYPE_PULLUP);
    
        GPIO_setDirectionMode(SPI_MOSI, GPIO_DIR_MODE_OUT);
        GPIO_setDirectionMode(SPI_MISO, GPIO_DIR_MODE_IN);
        GPIO_setDirectionMode(SPI_CLK, GPIO_DIR_MODE_OUT);
        GPIO_setDirectionMode(SPI_CS_1, GPIO_DIR_MODE_OUT);
    
        GPIO_setQualificationMode(SPI_MOSI, GPIO_QUAL_ASYNC);
        GPIO_setQualificationMode(SPI_MISO, GPIO_QUAL_ASYNC);
        GPIO_setQualificationMode(SPI_CLK, GPIO_QUAL_ASYNC);
        GPIO_setQualificationMode(SPI_CS_1, GPIO_QUAL_ASYNC);
    
        GPIO_setPinConfig (GPIO_63_SPISIMOB);
        GPIO_setPinConfig (GPIO_64_SPISOMIB);
        GPIO_setPinConfig (GPIO_65_SPICLKB);
    
        EDIS;
    
        //
        // Must put SPI into reset before configuring it
        //
        SPI_disableModule(SPIB_BASE);
    
        //
        // SPI configuration. Use a 1MHz SPICLK and 16-bit word size.
        //
    
        SPI_setConfig(SPIB_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA1,
                      SPI_MODE_MASTER, BAUD_RATE, 16);
        SPI_disableLoopback(SPIB_BASE);
        SPI_setEmulationMode(SPIB_BASE, SPI_EMULATION_STOP_AFTER_TRANSMIT);
    
        //FIFO
    
        SPI_enableFIFO(SPIB_BASE);
        
        SPI_enableModule(SPIB_BASE);
    
    }
    
    void ads_sys_command(uint16_t command)
    {
        GPIO_writePin (SPI_CS_1, 0);
        SPI_CYCLE_NOP(18 * BAUD_RATE/DEVICE_SYSCLK_FREQ);
    
        command = command<<8;
        SPI_writeDataNonBlocking(SPIB_BASE, command);
    
        SPI_CYCLE_NOP(18 * BAUD_RATE/DEVICE_SYSCLK_FREQ);
        GPIO_writePin (SPI_CS_1, 1);
    }
    
    void ads_write_reg(uint16_t address, uint16_t reg_data)
    {
    
        GPIO_writePin (SPI_CS_1, 0);
        SPI_CYCLE_NOP(18 * BAUD_RATE/DEVICE_SYSCLK_FREQ);
    
        address = (0x40|address)<<8;
        reg_data = reg_data<<8;
        SPI_writeDataNonBlocking(SPIB_BASE, address);
        SPI_writeDataNonBlocking(SPIB_BASE, reg_data);
    
        SPI_CYCLE_NOP(18 * BAUD_RATE/DEVICE_SYSCLK_FREQ);
        GPIO_writePin (SPI_CS_1, 1);
    }
    
    uint16_t ads_read_reg (uint16_t address)
    {
        uint16_t dummy_data = 0x00;
        uint16_t rData[3];
        char i = 0;
    
        GPIO_writePin (SPI_CS_1, 0);
        SPI_CYCLE_NOP(18 * BAUD_RATE/DEVICE_SYSCLK_FREQ);
    
        address = (0x20|address)<<8;
        SPI_writeDataNonBlocking(SPIB_BASE, address);
        SPI_writeDataNonBlocking(SPIB_BASE, dummy_data);
    
        SPI_CYCLE_NOP(18 * BAUD_RATE/DEVICE_SYSCLK_FREQ);
        GPIO_writePin (SPI_CS_1, 1);
    
        for (i=0; i<4; i++)
        {
            rData[i] = SPI_readDataNonBlocking(SPIB_BASE);
        }
        return (rData[2]);
    }
    
    void ads_reset ()
    {
        ads_sys_command(ADS_RESET);
    
        ads_sys_command(ADS_SDATAC);
    
        if (ads_read_reg(ID) != ID_VALUE)
        {
            while (1)
            {
    
            }
        }
    }
    #ifndef SPI_ADS_H_
    #define SPI_ADS_H_
    
    #include "driverlib.h"
    #include "device.h"
    
    typedef char    uint8_t;
    
    #define SPI_CYCLE_NOP0(n)  __asm(" RPT #(" #n ") || NOP")
    #define SPI_CYCLE_NOP(n)   SPI_CYCLE_NOP0(n)
    
    #define BAUD_RATE       1000000
    
    #define SPI_MOSI        63
    #define SPI_MISO        64
    #define SPI_CLK         65
    #define SPI_CS_1        66
    
    #define ID_VALUE        0x62
    
    #define ID              0x00
    #define CONFIG1         0x01
    #define CONFIG2         0x02
    #define CONFIG3         0x03
    #define LOFF            0x04
    
    #define CH1SET          0x05
    #define CH2SET          0x06
    #define CH3SET          0x07
    #define CH4SET          0x08
    #define CH5SET          0x09
    #define CH6SET          0x0A
    #define CH7SET          0x0B
    #define CH8SET          0x0C
    
    #define RLD_SENSP       0x0D
    #define RLD_SENSN       0x0E
    #define LOFF_SENSP      0x0F
    #define LOFF_SENSN      0x10
    #define LOFF_FLIP       0x11
    
    #define LOFF_STATP      0x12
    #define LOFF_STATN      0x13
    
    #define GPIO            0x14
    #define PACE            0x15
    #define RESP            0x16
    #define CONFIG4         0x17
    #define WCT1            0x18
    #define WCT2            0x19
    
    #define ADS_WAKEUP      0x02
    #define ADS_STANDBY     0x04
    #define ADS_RESET       0x06
    #define ADS_START       0x08
    #define ADS_STOP        0x0A
    #define ADS_RDATAC      0x10
    #define ADS_SDATAC      0x11
    #define ADS_RDATA       0x12
    
    void init_spi_ads       (void);
    void ads_sys_command    (uint16_t command);
    void ads_write_reg      (uint16_t address, uint16_t reg_data);
    uint16_t ads_read_reg   (uint16_t address);
    void ads_reset          (void);
    
    #endif /* SPI_ADS_H_ */

  • Hi Matheus,

    Please find my answers below:

    1) Do I need to use interruption when using spi's fifo?
    [Praveen] : Yes, You can optionally use the interrupt if you are CPU bandwidth limited. You can refer to the spi_ex2_loopback_fifo_interrupts example in c2000ware for fifo configurations.
     
    2) Do 8 bits word SPI works when fifo is enable? Because as I see on my programm it only start to transmite when the buffer gets 16 bits, even when I change to 8 bits word SPI config.
    [Praveen]: Yes, FIFO works for all the valid configurations of SPICHAR register. Please refer to "Data Format" section under SPI chapter in the TRM.
    The data has to be properly justified based on TX/RXBUF

    3) I'm no used to work with fifo. As I understand, there are no instruction to fill the fifo and other instruction to start the spi transfer, are there?
    [Praveen]: No there is not, If the shift register is idle, any writes into FIFO will trigger a transfer.

    Regards,
    Praveen

  • Hi Matheus,

    Since, we havent heard from you for a week, we presume your queries are resolved. I am moving this thread to resolved state.

    If you are still facing the issue, you may reject the resolution and reply to this thread. If the thread gets locked, please create a new thread

    Regards,
    Praveen