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: bq79600+bq79612

Part Number: BQ79600-Q1

Tool/software:

Hello there,
I am reading cell voltages using bq79600 and bq79612. Since this bq79612 communicates as a daisychain, when there is a problem in the cable of one of the modules, I lose the data of the future module, I want to use ring communication to prevent this. when it happens, I want to switch to the south direction and read the modules after the error, then switch back to the north direction and read again, is there a sample code for this or a place where you can give a reference because I can read in the south and north directions separately, but I cannot do a south and a north in the same loop

Error_Codes_enum PAL_BQ79600_ReadCellVoltages(BQ7961x_Modules_enum id)
{
    Uint16 MSB_register = (VCELL11_HI >>8) & 0xFF;
    Uint16 LSB_register = VCELL11_HI & 0xFF;
    Uint16 cell_number = 11;
    Uint16 receiveDataLength = cell_number *2;
    Uint16 i = 0;
//    Uint16 a = 0;
    Error_Codes_enum stats = ERROR_CODES_SUCCESS;
    CRC16_t crc16;
    Uint16 readCellVoltagesArray[7]= {0x80, id, MSB_register, LSB_register, (receiveDataLength - 1), 0x00, 0x00};
    CRC16_CalculateCRC16IBMAndWriteReverse(readCellVoltagesArray, 7);
//    a = id;
    HAL_SCI_EmptyRXFIFO(BQ79600_Module.UARTPort);
    HAL_SCI_write_bytes(BQ79600_Module.UARTPort, readCellVoltagesArray, 7);

        stats = HAL_SCI_Read_Into_CustomBuffer(BQ79600_Module.UARTPort, &(BQ79600_Module.Buffer[0]), 30,(6+ receiveDataLength));

        if (stats == ERROR_CODES_SUCCESS)
        {
            CRC16_CalculateCRC16IBM(BQ79600_Module.Buffer,(receiveDataLength+4), &crc16);

            if (BQ79600_Module.Buffer[(receiveDataLength+4)] != crc16.Bytes.LowByte || BQ79600_Module.Buffer[(receiveDataLength+5)] != crc16.Bytes.HighByte)
            {
                for (i = 0; i < 16; i++)
                {
//                    ActiveBattery.Modules[BQ79600_Module.Buffer[1]].Cells[i].RawVoltage = 0xFFFF;
//                    ActiveBattery.Modules[BQ79600_Module.Buffer[1]].Cells[i].CellVoltage = 0xFFFF;
                }
                return ERROR_CODES_CRC16ERROR;
            }
            if ((BQ79600_Module.Buffer[0] == (receiveDataLength-1)) && (BQ79600_Module.Buffer[2] == MSB_register) && (BQ79600_Module.Buffer[3] == LSB_register))
            {
                for (i = 4; i<(receiveDataLength+4); i+=2)
                {
                    BQ7961x_Modules[id].raw_Vcell[11-((i-4)/2)] = (BQ79600_Module.Buffer[i] << 8) +  BQ79600_Module.Buffer[i+1];
                    BQ7961x_Modules[id].Vcell[11-((i-4)/2)] = (Uint16)(BQ7961x_Modules[id].raw_Vcell[11-((i-4)/2)] * VCELL_COEFF);
                }
            }
        }
        else
        {

//            PAL_BQ79600_ReverseDirection(a);
//            Fail_Module_id = a;
            return ERROR_CODES_SERIAL_COMMUNICATION_ERROR;

        }
//    }
//    DELAY_US(50);
    return ERROR_CODES_SUCCESS;
}
Uint16 PAL_BQ79600_ReverseDirection(Uint16 id)
{
    BQ7961x_Modules_enum j;

    PAL_BQ79600_WriteSingleDevice(MODULE_BQ79600_NOT_USED, CONTROL1, 0x80); // change base device direction
    DELAY_US(10);

//    PAL_BQ79600_WriteSingleDevice(BQ7961x_MODULE_8, COMM_CTRL, 0x02);
//    DELAY_US(10);

    PAL_BQ79600_WriteMultiDevices(REVERSE, COMM_CTRL, 0x02);
    DELAY_US(10);

    PAL_BQ79600_WriteMultiDevices(REVERSE, CONTROL1, 0x80);  //change the stack device direction
    DELAY_US(10);


    //EnableAutoAddressing
    PAL_BQ79600_WriteMultiDevices(BROADCAST, CONTROL1, 0x81);
    DELAY_US(10);

    //Set stack device address for 8 stack
//    for (j = MODULE_BQ79600_NOT_USED; j < BQ7961x_MODULE_MAXNUM; j++)
//    {
//        PAL_BQ79600_WriteMultiDevices(BROADCAST, DIR1_ADDR, j);
//        DELAY_US(10);
//    }

    //Set stack device address for 8 stack
    for (j = BQ7961x_MODULE_8; j >= id; j--)
    {
        PAL_BQ79600_WriteMultiDevices(BROADCAST, DIR1_ADDR, j);
        DELAY_US(10);
    }

    PAL_BQ79600_WriteSingleDevice(MODULE_BQ79600_NOT_USED, COMM_CTRL, 0x00);
    DELAY_US(10);

    //Stack All Devices
    PAL_BQ79600_WriteMultiDevices(BROADCAST, COMM_CTRL, 0x02);
    DELAY_US(10);

    //Set Top Stack
    PAL_BQ79600_WriteSingleDevice(id, COMM_CTRL, 0x03);
    DELAY_US(10);

    return ERROR_CODES_REVERSE_DIRECTION;
}
void PAL_CheckCommunicationError(Uint16 commStatus, Uint16 currentModule)
{
    if ( commStatus == ERROR_CODES_SERIAL_COMMUNICATION_ERROR)
    {
        commErrorFlag = 1;
        failedModuleID = currentModule;
        direction = 1;
        reverse_command= 1;
//        currentModule--;
    }
    else
    {
        commErrorFlag = 0;
        if(direction == 1 && currentModule == failedModuleID)
        {
            direction = 0;
        }
    }
}
Uint16 PAL_BQ79600_SendNormalDirectionCommand(Uint16 id)
{

    BQ7961x_Modules_enum j;

    PAL_BQ79600_WriteSingleDevice(MODULE_BQ79600_NOT_USED, CONTROL1, 0x00); // change base device direction
     DELAY_US(10);

 //    PAL_BQ79600_WriteSingleDevice(BQ7961x_MODULE_8, COMM_CTRL, 0x02);
 //    DELAY_US(10);

     PAL_BQ79600_WriteMultiDevices(REVERSE, COMM_CTRL, 0x02);
     DELAY_US(10);

     PAL_BQ79600_WriteMultiDevices(REVERSE, CONTROL1, 0x00);  //change the stack device direction
     DELAY_US(10);


     //EnableAutoAddressing
     PAL_BQ79600_WriteMultiDevices(BROADCAST, CONTROL1, 0x01);
     DELAY_US(10);

     //Set stack device address for 8 stack
     for (j = MODULE_BQ79600_NOT_USED; j < BQ7961x_MODULE_MAXNUM; j++)
     {
         PAL_BQ79600_WriteMultiDevices(BROADCAST, DIR1_ADDR, j);
         DELAY_US(10);
     }

     PAL_BQ79600_WriteSingleDevice(MODULE_BQ79600_NOT_USED, COMM_CTRL, 0x00);
     DELAY_US(10);

     //Stack All Devices
     PAL_BQ79600_WriteMultiDevices(BROADCAST, COMM_CTRL, 0x02);
     DELAY_US(10);

     //Set Top Stack
     PAL_BQ79600_WriteSingleDevice(id-1, COMM_CTRL, 0x03);
     DELAY_US(10);
     return 0 ;
}
void PAL_HandleDirection(BQ7961x_Modules_enum moduleId)
{
    Error_Codes_enum commStatus = ERROR_CODES_SUCCESS;


    if (direction == 0) // Normal (düz) yön
    {
        commStatus = PAL_BQ79600_ReadCellVoltages(moduleId);
        PAL_CheckCommunicationError(commStatus, moduleId);

        if (commErrorFlag == 0)  // Eğer hata yoksa bir sonraki modüle geç
        {
            currentModule++;  // Düz yönde ilerle
            if (currentModule > BQ7961x_MODULE_8)  // Modüller biterse tekrar başa dön
            {
                currentModule = 1;
            }
        }
    }
 
    else if (direction == 1 && currentModule >= 1) // Ters yön
    {
        if (reverse_command)
        {
            PAL_BQ79600_ReverseDirection(moduleId);  // Ters yönde iletişim başlat
            reverse_command = 0;
        }

        commStatus = PAL_BQ79600_ReadCellVoltages(moduleId);
        PAL_CheckCommunicationError(commStatus, moduleId);

        if (commErrorFlag == 0)  // Hata düzelirse düz yöne geç
        {
            PAL_BQ79600_SendNormalDirectionCommand(moduleId);
            direction = 0;  // Yönü düz olarak değiştir
            currentModule++;  // Düz yönde devam etmek için bir sonraki modüle geç
            if (currentModule > BQ7961x_MODULE_8)  // Modüller biterse başa dön
            {
                currentModule = 1;
            }
        }
        else
        {
            currentModule--;  // Hata devam ederse ters yönde ilerlemeye devam et
            if (currentModule == 0)  // Eğer başa gelirsek
            {
                currentModule = BQ7961x_MODULE_8;  // Modüller başa döner
            }
        }
    }
}


APPL_Frames_ActiveInitial();

PAL_HandleDirection(currentModule);
My main code is as follows