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.

BQ79600-Q1: 自动编码失败

Part Number: BQ79600-Q1


   系统的示意图如下所示:

    MCU对BQ79600进行初始化的时候,MCU通过Wakeup ping可以唤醒桥接芯片BQ79600, 但是在进行自动编码的时候,MCU检测到SPI_RDY信号一直为低,导致无法与BQ79600进行通信,从而陷入无限等待之后,编码过程无法通过。

   BQ79600的初始化代码如下:

  

void Task_AfeComm_Init(void)
{
#if 1
    //INITIALIZE BQ79600
    //two wakes in case the MCU had nCS and MOSI = 0 at start (which would put the device in shutdown)
    //or in case the device was previously put in shutdown through a shutdown ping
    SpiWake79600(); //send wake ping to bridge device
    SysDelay_mS(4); //wait tSU(WAKE_SHUT), at least 3.5ms
    //SpiWake79600(); //send wake ping to bridge device
    //SysDelay_mS(4); //tSU(WAKE_SHUT), at least 3.5ms

    //INITIALIZE BQ79616-Q1 STACK
    SpiWriteReg(0, CONTROL1, 0x20, 1, FRMWRT_SGL_W); //send wake tone to stack devices
    SysDelay_mS(12*TOTALBOARDS); //wake tone duration is ~1.6ms per board + 10ms per board for each device to wake up from shutdown = 11.6ms per 616 board.

    //AUTO-ADDRESS
    SpiAutoAddress(); //auto address sequence

    //RESET ANY COMM FAULT CONDITIONS FROM STARTUP
    SpiWriteReg(0, FAULT_RST1, 0xFF, 1, FRMWRT_STK_W); //Reset faults on stacked devices
    SpiWriteReg(0, FAULT_RST2, 0xFF, 1, FRMWRT_STK_W); //Reset faults on stacked devices
    SpiWriteReg(0, Bridge_FAULT_RST, 0x22, 1, FRMWRT_SGL_W); //Reset FAULT_COMM and FAULT_SYS on bridge device

    //ENABLE BQ79616-Q1 MAIN ADC
    SpiWriteReg(0, ACTIVE_CELL, ACTIVE_CELL_16S, 1, FRMWRT_STK_W); //Set all cells to active
    SpiWriteReg(0, GPIO_CONF1, ((GPIO_CFG_ADC << 3) | GPIO_CFG_ADC), 1, FRMWRT_STK_W); //Configure temp samp
    SpiWriteReg(0, GPIO_CONF2, ((GPIO_CFG_ADC << 3) | GPIO_CFG_ADC), 1, FRMWRT_STK_W); //Configure temp samp
    SpiWriteReg(0, GPIO_CONF3, ((GPIO_CFG_ADC << 3) | GPIO_CFG_ADC), 1, FRMWRT_STK_W); //Configure temp samp
    SpiWriteReg(0, GPIO_CONF4, ((GPIO_CFG_ADC << 3) | GPIO_CFG_ADC), 1, FRMWRT_STK_W); //Configure temp samp
    SpiWriteReg(0, ADC_CTRL1, (ADC_MAIN_GO_START | ADC_RUNMODE_CONTINUE), 1, FRMWRT_STK_W);   //continuous run and MAIN_GO
    //SysDelay_uS(5*TOTALBOARDS + 192);                       //5us reclocking per board and 192us for round robin to complete
#endif
    TMR_InitTimer(TID_AFE_COMM, 200);
}

自动编码过程的代码如下:

void SpiAutoAddress()
{
    UINT8 BoardIdx;
    UINT8 AutoAddr_RspData[8] = { 0 };

    //DUMMY WRITE TO SNCHRONIZE ALL DAISY CHAIN DEVICES DLL (IF A DEVICE RESET OCCURED PRIOR TO THIS)
    SpiWriteReg(0, OTP_ECC_DATAIN1, 0x00, 1, FRMWRT_STK_W);
    SpiWriteReg(0, OTP_ECC_DATAIN2, 0x00, 1, FRMWRT_STK_W);
    SpiWriteReg(0, OTP_ECC_DATAIN3, 0x00, 1, FRMWRT_STK_W);
    SpiWriteReg(0, OTP_ECC_DATAIN4, 0x00, 1, FRMWRT_STK_W);
    SpiWriteReg(0, OTP_ECC_DATAIN5, 0x00, 1, FRMWRT_STK_W);
    SpiWriteReg(0, OTP_ECC_DATAIN6, 0x00, 1, FRMWRT_STK_W);
    SpiWriteReg(0, OTP_ECC_DATAIN7, 0x00, 1, FRMWRT_STK_W);
    SpiWriteReg(0, OTP_ECC_DATAIN8, 0x00, 1, FRMWRT_STK_W);

    //ENABLE AUTO ADDRESSING MODE
    /*
    bit7  DIR_SEL = 选择菊花链通信方向。
                0 = 在两个器件以菊花链方式连接的情况下,命令帧从下部器件的 COMH 传输到下一个器件的 COML。
                1 = 在两个器件以菊花链方式连接的情况下,命令帧从下部器件的 COML 传输到下一个器件的 COMH。
    bit6  SEND_SHUTDOWN = 沿堆栈向上,向下一个器件发送SHUTDOWN音。接收此位设置的器件不受影响。读取时该位被清除。
                0 = 就绪
                1 = 沿堆栈向上发送关断音
    bit5  SEND_WAKE = 沿堆栈向上,向下一个器件发送唤醒音。读取时该位被清除。
                0 = 就绪
                1 = 沿堆栈向上,向下一个器件发送唤醒音。
    bit4  SEND_SLPTOACT = 沿堆栈向上,发送 SLEEPtoACTIVE 音。读取时该位被清除。
                0 = 就绪
                1 = 沿堆栈向上,发送 SLEEPtoACTIVE 音
    bit3  GOTO_SHUTDOWN = 将器件转换为 SHUTDOWN 模式。读取时该位被清除。
                0 = 就绪
                1 = 进入 SHUTDOWN 模式
    bit2  GOTO_SLEEP = 将器件转换为 SLEEP 模式。读取时该位被清除。
                0 = 就绪
                1 = 进入 SLEEP 模式
    bit1  SOFT_RESET = 将数字复位为 OTP 默认值。读取时该位被清除。设置该位将使器件向上层堆栈器件生成唤醒音。
                0 = 就绪
                1 = 复位器件
    bit0  ADDR_WR = 使器件启动自动寻址。设置该位时,器件不会转发它接收到的第一个转换,从而允许将器件地址写入单个器件。
                0 = 不执行自动寻址。器件正常转发通信事务。
                1 = 正在对器件自动寻址;将不会转发它收到的第一个通信事务。
    */
    SpiWriteReg(0, CONTROL1, 0X01, 1, FRMWRT_ALL_W);

    //SET ADDRESSES FOR EVERY BOARD
    //for(BoardIdx = 0; BoardIdx < PARA_GetUint16(PID_SYS_BMU_NUM); BoardIdx++)
    for(BoardIdx = 0; BoardIdx < TOTALBOARDS; BoardIdx++)
    {
        SpiWriteReg(0, DIR0_ADDR, BoardIdx, 1, FRMWRT_ALL_W);
    }

    //BROADCAST WRITE TO SET ALL DEVICES AS STACK DEVICE
    //Bit0: TOP_STACK. 将器件定义为堆栈中地址最高的器件. 0=不是ToS器件; 1=是ToS器件
    //Bit1: STACK_DEV. 将器件定义为菊花链配置中的基底器件或堆栈器件. 0=基底器件; 1=堆栈器件
    SpiWriteReg(0, COMM_CTRL, 0x02, 1, FRMWRT_ALL_W);

    //SET THE HIGHEST DEVICE IN THE STACK AS BOTH STACK AND TOP OF STACK
    SpiWriteReg(TOTALBOARDS-1, COMM_CTRL, 0x03, 1, FRMWRT_SGL_W);

    //SYNCRHONIZE THE DLL WITH A THROW-AWAY READ
    SpiReadReg(0, OTP_ECC_DATAIN1, AutoAddr_RspData, 1, 100, FRMWRT_STK_R);
    //MCU is blocked while read register OTP_ECC_DATAIN2
    SpiReadReg(0, OTP_ECC_DATAIN2, AutoAddr_RspData, 1, 100, FRMWRT_STK_R);
    SpiReadReg(0, OTP_ECC_DATAIN3, AutoAddr_RspData, 1, 100, FRMWRT_STK_R);
    SpiReadReg(0, OTP_ECC_DATAIN4, AutoAddr_RspData, 1, 100, FRMWRT_STK_R);
    SpiReadReg(0, OTP_ECC_DATAIN5, AutoAddr_RspData, 1, 100, FRMWRT_STK_R);
    SpiReadReg(0, OTP_ECC_DATAIN6, AutoAddr_RspData, 1, 100, FRMWRT_STK_R);
    SpiReadReg(0, OTP_ECC_DATAIN7, AutoAddr_RspData, 1, 100, FRMWRT_STK_R);
    SpiReadReg(0, OTP_ECC_DATAIN8, AutoAddr_RspData, 1, 100, FRMWRT_STK_R);

    //OPTIONAL: read back all device addresses
    //for(BoardIdx = 0; BoardIdx < PARA_GetUint16(PID_SYS_BMU_NUM); BoardIdx++)
    for(BoardIdx = 0; BoardIdx < TOTALBOARDS; BoardIdx++)
    {
        SpiReadReg(BoardIdx, DIR0_ADDR, AutoAddr_RspData, 1, 100, FRMWRT_SGL_R);
    }

    //OPTIONAL: read register address 0x2001 and verify that the value is 0x14
    SpiReadReg(0, 0x2001, AutoAddr_RspData, 1, 100, FRMWRT_SGL_R);

    return;
}

请帮忙分析一下是什么原因,导致MCU在读取寄存器0x344 (OTP_ECC_DATAIN2)的时候,就一直提示SPI通信无法进行了。