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