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.

[参考译文] BOOSTXL-DRV8323RS:SPI 通信失败、读取和写入不工作

Guru**** 2393725 points
Other Parts Discussed in Thread: BOOSTXL-DRV8323RS, LAUNCHXL-F280025C, DRV8323, BQ76952

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/1459859/boostxl-drv8323rs-spi-communication-failed-read-and-write-not-working

器件型号:BOOSTXL-DRV8323RS
主题中讨论的其他器件: LAUNCHXL-F280025CDRV8323BQ76952

工具与软件:

您好!

我有基于 launchxl-f280025c + boostxl-drv8323rs 组合的定制电路板、只是更改了 EN、SOMI 和 SIMO 引脚等微小引脚

LaunchXL-F280025C + Boostxl-DRV8323RS
SPI-A 时钟 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
故障 GPIO_34_GPIO34 GPIO_34_GPIO34


1. HAL_setParams -> HAL_setupGPIO

在这个函数内部、有一个预定义符号 DRV_CS_GPIO、默认情况下会被绕过、这是我的第一个问题:CS 引脚在哪里设置为高电平和低电平? 因为在 DRV8323_readSPI 和 DRV8323_writeSPI 函数内部、CS 引脚也会 被旁路 ?

    // 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:

EN 和 CS 分别分配给 gpioNumber_EN 和 gpioNumber_CS

3. HAL_MTR_setGateDriver -> HAL_enableDRV -> DRVIC_ENABLE:

EN 引脚设置为1和 DRV 使能、电机可以旋转和识别。
在此函数内、DRV8323_readSPI (Handle、DRV8323_ADDRESS_STATUS_0)和 DRV8323_STATUS00_FAULT_BITS)!= 0无法判断芯片通信是否正常、因为 SPI 失败失败位是否为0

4. HAL_setupDRVSPI -> DRVIC_setupSPI

在该函数内部、为了立即读取控制寄存器3、它应该更新 drv8323Vars->ctrlReg03.all

但最后它保持为0

//读取控制寄存器3
//所有位默认值都为1、IDRIVEP_HS = 1000mA、IDRIVEN_HS = 2000mA
drvRegAddr = DRV8323_ADDRESS_CONTROL_3;
drvDataNew = DRV8323_readSPI (handle、drvRegAddr);
drv8323Vars->ctrlReg03.all = drvDataNew;

5.如前所述、在 DRV8323_readSPI 和 DRV8323_writeSPI 内部、由于绕过该引脚、因而无法选择操作  

#if defined (DRV_CS_GPIO)

  GPIO_writePin (obj->gpioNumber_CS、0);

  GPIO_writePin (obj->gpioNumber_CS、0);

#endif  // DRV_CS_GPIO

CS 引脚操作在哪里发生? 出什么问题了?  

Danny

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Danny:

    请注意、可以通过两种方法实现 SPI 控制器与外设之间的通信。

    1. 芯片选择/CS、需要手动控制 CS GPIO
    2. 内置 PTE (原 STE)功能允许 SPI 外设自动控制发送信号。 这会将 CS 控制交给外设、从而更大限度地减少代码要求并最大程度地减少 ISR 中花费的时间。

    默认情况下、通用电机控制实验 F28002x + DRV8323RS 使用该功能。

    声明:  

    确保 SPIA_STE 引脚或 CS_GPIO 引脚(无论您要使用哪一个引脚)正确连接到 DRV8323RS 的 nSCS 引脚。 我个人建议继续使用 STE 功能-它确实省去了操作 CS GPIO 的大量麻烦。

    此致、
    Jason Osborn

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Jason:

    我的电路板将 GPIO_8连接到 DRV8323 nSCS 引脚遵循 TI 示例、您是说  

    1.我使用 GPIO_0_SPIA_STE、GPIO_5_SPIA_STE、GPIO_11_SPIA_STE、GPIO_19_SPIA_STE 重新设计电路板是否连接到 nSCS?

    2.或者沿用我当前的电路板设计、GPIO_8连接到 nSCS、并删除  如下所示的预定义符号 DRV_CS_GPIO  

    HAL_setupGPIO 函数使用 GPIO_8_GPIO8而不是 STE、默认设置为高电平  

    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);
        .
        .
        .
    }

    在 DRV8323_readSPI 和 DRV8323_writeSPI 函数内部、 手动将 CS 引脚拉至低电平、例如 GPIO_writePin (obj->gpioNumber_CS、0)、然后将 CS 设置为高电平

    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
    

    下面是 spi_ex6_eeprom 示例、其读取和写入操作的方式...。  

    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;
    }

    之所以需要使用 GPIO 而不是 STE、是因为我需要稍后在定制电路板上添加像 BQ76952这样的 BMS 模块!

    还有其他建议吗?

    Danny

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Danny:

    要清楚,我不是试图建议改变你的板基于我所说的! 我尝试做2件事:

    1. 确保了解 STE 功能。

    2. 确保  按照用户指南和代码内注释的说明跳接或以其他方式连接到 Booster Pack J2-18的 STE 或 CS (无论您要使用哪一种)。

    现在、我确实有一些建议:

    请告诉我这些建议是否有用!

    此致、
    Jason Osborn