Initial rough start to the BQ76PL536A (or BQ76PL536A-Q1) code. Free to use as long as you make any changes/improvements publicly available. Please notify me of any improvements.
bq76pl536a.cpp
- Committer:
- dmwahl
- Date:
- 2021-07-25
- Revision:
- 3:a0e12d12f780
- Parent:
- 2:7083c7257556
File content as of revision 3:a0e12d12f780:
///----------------------------------------------------------------- /// Description: BQ76PL536A Driver /// Author: David Wahl /// Date: 13-JUL-2021 /// Notes: Initial release /// /// Revision History: /// Name: Date: Description: ///----------------------------------------------------------------- #include "bq76pl536a.h" //=========================================================================== // Default constructor. Setup spi interface and run init functions BQ76PL536A::BQ76PL536A(SPI _spi, PinName _cs, u8t _numDev, u16t _cov, u16t _cuv, u8t _balanceTimeout, bool _balanceEnabled) //=========================================================================== : spi(_spi), cs(_cs), numDev(_numDev), cov(_cov), cuv(_cuv), balanceTimeout(_balanceTimeout), balanceEnabled(_balanceEnabled) { DigitalOut cs(_cs); cs = 1; spi.format(8,1); spi.frequency(2.5e6); cs=0; wait_ms(1); cs=1; wait_ms(1); softReset(); setAddresses(); }; //=========================================================================== // Convert raw values to cell voltage float BQ76PL536A::cellVolts(u8t lobyte, u8t hibyte) //=========================================================================== { float cv = (((((u16t)lobyte << 8) + (u16t)hibyte)*6250/16383)/1000.0); // [V] //float cv = (((lobyte * 256) + hibyte)*6250/16383); // [mV] return cv; }; //=========================================================================== //=========================================================================== // Start conversion on all devices void BQ76PL536A::adcConvert() //=========================================================================== { write(BROADCAST_ADDR, ADC_CONVERT_REG, 1); } //=========================================================================== // Reset all devices in stack void BQ76PL536A::softReset() //=========================================================================== { write(BROADCAST_ADDR, RESET_REG, BQ76PL536A_RESET); } //=========================================================================== // Address devices void BQ76PL536A::setAddresses() //=========================================================================== { for(u8t i=0; i<numDev; i++) { write(DISCOVERY_ADDR, ADDRESS_CONTROL_REG, i+1); } } /*//=========================================================================== // Device status u8t BQ76PL536A::devStatus() //=========================================================================== { //update to use numDev u8t currentStatus[1]; read(1,DEVICE_STATUS_REG,1,currentStatus); return currentStatus[0]; } //===========================================================================*/ //=========================================================================== // Read one or more bytes from the BQ76 device stack. Count does not include CRC byte. bool BQ76PL536A::readAll(u8t deviceAddress) //=========================================================================== { //error = 0; read(deviceAddress,0,64,bqPackData); return false; } //=========================================================================== // Read one or more bytes from the BQ76 device stack. Count does not include CRC byte. bool BQ76PL536A::read(u8t deviceAddress, u8t regAddress, u8t count, u8t *pRegisterValue) //=========================================================================== { error = 0; bool crcGood = true; u8t logicalAddress = (deviceAddress << 1 | 0); // Shift address left 1 bit u8t crcInput[3+count]; crcInput[0] = logicalAddress; crcInput[1] = regAddress; crcInput[2] = count; cs = 0; spi.write(logicalAddress); spi.write(regAddress); spi.write(count); //Read data. Last byte is CRC data. for (int i = 0; i <= count; i++) { pRegisterValue[i] = spi.write(0x00); if (i != count) { crcInput[3+i] = pRegisterValue[i]; } if (i == count) { if (pec(crcInput,3+count) != pRegisterValue[i]) { error = 1; crcGood = false; } } } cs = 1; //End of transmission, slave select high return crcGood; } //=========================================================================== // Write one byte to the BQ76 device stack. Should add code to read back written register and compare... void BQ76PL536A::write(u8t deviceAddress, u8t regAddress, u8t regData) //=========================================================================== { u8t logicalAddress = (deviceAddress << 1 | 1); // Shift address left one bit and set LSB u8t crcInput[3] = {logicalAddress, regAddress, regData}; cs = 0; spi.write(logicalAddress); spi.write(regAddress); spi.write(regData); spi.write(pec(crcInput, sizeof(crcInput)/sizeof(crcInput[0]))); cs = 1; } //=========================================================================== // Calculate CRC byte to verify data integrity u8t BQ76PL536A::pec(u8t crcBuffer[], u8t crcLength) //=========================================================================== { //u8t crcTestInput[3] = {0x01,0x3b,0x01}; // should return 0x02 u8t crc = 0; u8t temp = 0; for (u8t i = 0; i < crcLength; i++) { temp = crc ^ crcBuffer[i]; crc = crcTable[temp]; } return crc; }