BOOSTXL-DRV8323RS: SPI communication failed, READ and WRITE not working

Part Number: BOOSTXL-DRV8323RS
Other Parts Discussed in Thread: LAUNCHXL-F280025C, DRV8323, BQ76952

Tool/software:

Hi,

I have custom board which is based on launchxl-f280025c + boostxl-drv8323rs combo just with minor pins changed like EN, SOMI and SIMO pins

Custom Board LaunchXL-F280025C + Boostxl-DRV8323RS
SPI-A Clock GPIO_12_SPIA_CLK GPIO_9_SPIA_CLK
SPI-A (SOMI) GPIO_13_SPIA_SOMI GPIO_10_SPIA_SOMI
SPI-A (SIMO) GPIO_16_SPIA_SIMO GPIO_11_SPIA_SIMO
EN  GPIO_31_GPIO31 GPIO_29_GPIO29
CS GPIO_8_GPIO8 GPIO_8_GPIO8
FAULT GPIO_34_GPIO34 GPIO_34_GPIO34


1. HAL_setParams -> HAL_setupGPIOs

inside this function, there's predefined symbol DRV_CS_GPIO, by default it's bypassed, here's my first question, where's CS pin set High and Low ? because inside DRV8323_readSPI and DRV8323_writeSPI function CS pin also bypassed ?

    // M1_DRV_SCS
#ifdef DRV_CS_GPIO
    GPIO_setPinConfig(GPIO_8_GPIO8);
    GPIO_writePin(8, 1);
    GPIO_setDirectionMode(8, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(8, GPIO_PIN_TYPE_PULLUP);
#else   // M1_DRV_SCS (Use a wire->J2-18)
    GPIO_setPinConfig(GPIO_8_GPIO8);
    GPIO_setDirectionMode(8, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(8, GPIO_PIN_TYPE_STD);
#endif

    // GPIO12->M1_DRV_SCLK*
    GPIO_setPinConfig(GPIO_12_SPIA_CLK);
    GPIO_setDirectionMode(12, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(12, GPIO_PIN_TYPE_PULLUP);

    // GPIO13->SPIA_SOMI->M1_DRV_SDO*
    GPIO_setPinConfig(GPIO_13_SPIA_SOMI);
    GPIO_setDirectionMode(13, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(13, GPIO_PIN_TYPE_PULLUP);

    // GPIO16->SPIA_SIMO->M1_DRV_SDI*
    GPIO_setPinConfig(GPIO_16_SPIA_SIMO);
    GPIO_setDirectionMode(16, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(16, GPIO_PIN_TYPE_PULLUP);

    // GPIO31->M1_DRV_ENABLE*
    GPIO_setPinConfig(GPIO_31_GPIO31);
    GPIO_writePin(31, 1);
    GPIO_setDirectionMode(31, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(31, GPIO_PIN_TYPE_STD);

2. HAL_MTR_setGateDriver -> HAL_setupGate :

both EN and CS assigned to gpioNumber_EN and gpioNumber_CS respectively

3. HAL_MTR_setGateDriver -> HAL_enableDRV -> DRVIC_enable :

EN pin set to 1 and DRV enable, Motor can spin and Identify.
inside this function DRV8323_readSPI(handle, DRV8323_ADDRESS_STATUS_0) & DRV8323_STATUS00_FAULT_BITS) != 0 can not tell if chip communicate is work or not because if SPI failed FAIL bit is 0

4. HAL_setupDRVSPI -> DRVIC_setupSPI

inside this function, for instant read control register 3, it should update drv8323Vars->ctrlReg03.all

but at the end it's remain 0

// Read Control Register 3
// all bit default value are 1, IDRIVEP_HS=1000mA, IDRIVEN_HS = 2000mA
drvRegAddr = DRV8323_ADDRESS_CONTROL_3;
drvDataNew = DRV8323_readSPI(handle, drvRegAddr);
drv8323Vars->ctrlReg03.all = drvDataNew;

5. as mentioned before, inside both DRV8323_readSPI and DRV8323_writeSPI has not CS select action because it's bypasses 

#if defined(DRV_CS_GPIO)

    GPIO_writePin(obj->gpioNumber_CS, 0);

    GPIO_writePin(obj->gpioNumber_CS, 0);

#endif  // DRV_CS_GPIO

Where's CS pin action take place ? what's went wrong ? 

Danny

  • Danny,

    Please note that there are 2 ways to enable communication from the SPI controller to a peripheral device.

    1. Chip Select/CS, which requires you to manually control the CS GPIO
    2. The built-in PTE (formerly STE) functionality, which allows the SPI peripheral to automatically control the transmit signal for you. This hands CS control to the peripheral, minimizing code requirements and minimizing how much time is spent in the ISR.

    By default, the Universal Motor Control Lab F28002x + DRV8323RS utilizes this functionality.

    Notice: 

    Make sure that the SPIA_STE pin or the CS_GPIO pin (whichever one you intend on using) is properly connected to the nSCS pin of the DRV8323RS. I personally recommend continuing to utilize the STE functionality- it definitely removes a lot of the hassle of manipulating the CS GPIO.

    Regards,
    Jason Osborn

  • Hi Jason,

    My board is connect GPIO_8 to DRV8323 nSCS pin follow TI example, do you mean 

    1. I re-design my board with either GPIO_0_SPIA_STE, GPIO_5_SPIA_STE, GPIO_11_SPIA_STE, GPIO_19_SPIA_STE connect to nSCS?

    2. or stay with my current board design which's GPIO_8 connect to nSCS, and remove the predefined symbols DRV_CS_GPIO like below 

    HAL_setupGPIOs function use GPIO_8_GPIO8 instead of STE, by default set to HIGH 

    void HAL_setupGPIOs(HAL_Handle handle)
    {
        .
        .
        .
        // GPIO8->CS
        GPIO_setPinConfig(GPIO_8_GPIO8);
        GPIO_writePin(8, 1);
        GPIO_setDirectionMode(8, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(8, GPIO_PIN_TYPE_PULLUP);
    
        // GPIO12->M1_DRV_SCLK*
        GPIO_setPinConfig(GPIO_12_SPIA_CLK);
        GPIO_setDirectionMode(12, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(12, GPIO_PIN_TYPE_PULLUP);
    
        // GPIO13->SPIA_SOMI->M1_DRV_SDO*
        GPIO_setPinConfig(GPIO_13_SPIA_SOMI);
        GPIO_setDirectionMode(13, GPIO_DIR_MODE_IN);
        GPIO_setPadConfig(13, GPIO_PIN_TYPE_PULLUP);
    
        // GPIO16->SPIA_SIMO->M1_DRV_SDI*
        GPIO_setPinConfig(GPIO_16_SPIA_SIMO);
        GPIO_setDirectionMode(16, GPIO_DIR_MODE_IN);
        GPIO_setPadConfig(16, GPIO_PIN_TYPE_PULLUP);
    
        // GPIO31->M1_DRV_ENABLE*
        GPIO_setPinConfig(GPIO_31_GPIO31);
        GPIO_writePin(31, 1);
        GPIO_setDirectionMode(31, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(31, GPIO_PIN_TYPE_STD);
        .
        .
        .
    }

    inside both DRV8323_readSPI and DRV8323_writeSPI function, manually pull CS pin to LOW e.g. GPIO_writePin(obj->gpioNumber_CS, 0), after that set CS to HIGH

    uint16_t DRV8323_readSPI(DRV8323_Handle handle, const DRV8323_Address_e regAddr)
    {
        DRV8323_Obj *obj = (DRV8323_Obj *)handle;
        uint16_t ctrlWord;
        uint16_t n;
        const uint16_t data = 0;
        volatile uint16_t readWord;
        volatile uint16_t WaitTimeOut = 0;
    
        volatile SPI_RxFIFOLevel RxFifoCnt = SPI_FIFO_RXEMPTY;
    
        // build the control word
        ctrlWord = (uint16_t)DRV8323_buildCtrlWord(DRV8323_CTRLMODE_READ, regAddr, data);
    
        // GPIO 8 CS PIN
        GPIO_writePin(obj->gpioNumber_CS, 0);
        GPIO_writePin(obj->gpioNumber_CS, 0);
    
    
        // wait for registers to update
        for(n = 0; n < 0x10; n++)
        {
            __asm(" NOP");
        }
    
        // reset the Rx fifo pointer to zero
        SPI_resetRxFIFO(obj->spiHandle);
        SPI_enableFIFO(obj->spiHandle);
    
        // wait for registers to update
        for(n = 0; n < 0x20; n++)
        {
            __asm(" NOP");
        }
    
        // write the command
        SPI_writeDataBlockingNonFIFO(obj->spiHandle, ctrlWord);
    
        // wait for two words to populate the RX fifo, or a wait timeout will occur
        while(RxFifoCnt < SPI_FIFO_RX1)
        {
            RxFifoCnt = SPI_getRxFIFOStatus(obj->spiHandle);
    
            if(++WaitTimeOut > 0xfffe)
            {
                obj->rxTimeOut = true;
            }
        }
    
        WaitTimeOut = 0xffff;
    
        // wait for registers to update
        for(n = 0; n < 0x100; n++)
        {
            __asm(" NOP");
        }
    
        // GPIO 8 CS PIN
        GPIO_writePin(obj->gpioNumber_CS, 1);
        GPIO_writePin(obj->gpioNumber_CS, 1);
    
    
        // Read the word
        readWord = SPI_readDataNonBlocking(obj->spiHandle);
    
        return(readWord & DRV8323_DATA_MASK);
    } // end of DRV8323_readSPI() function

    void DRV8323_writeSPI(DRV8323_Handle handle, const DRV8323_Address_e regAddr, const uint16_t data)
    {
        DRV8323_Obj *obj = (DRV8323_Obj *)handle;
        uint16_t ctrlWord;
        uint16_t n;
    
        // build the control word
        ctrlWord = (uint16_t)DRV8323_buildCtrlWord(DRV8323_CTRLMODE_WRITE, regAddr, data);
    
        // GPIO 8 PIN
        GPIO_writePin(obj->gpioNumber_CS, 0);
        GPIO_writePin(obj->gpioNumber_CS, 0);
     
    
        // wait for GPIO
        for(n = 0; n < 0x10; n++)
        {
            __asm(" NOP");
        }
    
        // reset the Rx fifo pointer to zero
        SPI_resetRxFIFO(obj->spiHandle);
        SPI_enableFIFO(obj->spiHandle);
    
        // wait for registers to update
        for(n = 0; n < 0x20; n++)
        {
            __asm(" NOP");
        }
    
        // write the command
        SPI_writeDataBlockingNonFIFO(obj->spiHandle, ctrlWord);
    
        // wait for registers to update
        for(n = 0; n < 0x100; n++)
        {
            __asm(" NOP");
        }
    
        // GPIO 8 PIN
        GPIO_writePin(obj->gpioNumber_CS, 1);
        GPIO_writePin(obj->gpioNumber_CS, 1);
     
    
        return;
    }  // end of DRV8323_writeSPI() function
    

    below is SPI_ex6_eeprom example the way its READ and WRITE action .... 

    void writeData(uint16_t address, uint16_t *data, uint16_t length, uint16_t txdly)
    {
        uint32_t base = SPIA_BASE;
    
        // Pull chip select low.
        CS_LOW;
    
        // Send the WRITE opcode.
        SPI_transmitByte(base, WRITE);
    
        // Send EEPROM address to write data
        SPI_transmitByte(base, address>>8);
        SPI_transmitByte(base, address);
    
        // Send data to be programmed
        SPI_transmitNBytes(base, data, length, txdly);
    
        // Pull chip select high.
        CS_HIGH;
    }
    
    //
    // Function to read data from the EEPROM
    // - address is the byte address of the EEPROM
    // - data is a pointer to an array of data being received
    // - length is the number of characters in the array to receive
    //
    void readData(uint16_t address, uint16_t *data, uint16_t length, uint16_t txdly)
    {
        uint32_t base = SPIA_BASE;
    
        CS_LOW;
    
        // Send the READ opcode.
        SPI_transmitByte(base, READ);
    
        // Send EEPROM address to write data
        SPI_transmitByte(base, address>>8);
        SPI_transmitByte(base, address);
    
        // Receive length number of bytes
        SPI_receiveNBytes(base, data, length, txdly);
    
    
        CS_HIGH;
    }

    the reason I need to use GPIO instead of STE because I need to add BMS module like BQ76952 later on my custom board!

    any further suggestions ?

    Danny

  • Danny,

    To be clear, I was not trying to advise altering your board based on what I said! I was trying to do 2 things:

    1. Ensure that you are aware of the STE functionality.

    2. Ensure that either STE or CS, whichever one you intend to use, is jumped or otherwise connected to Booster Pack J2-18, as instructed by both the User's Guide and in-code comments.

    Now, I do have suggestions:

    Let me know if these suggestions are useful!

    Regards,
    Jason Osborn