diff --git a/CMakeLists.txt b/CMakeLists.txt index 74505cb..6f45c2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ project(${APP_TARGET}) add_library(${APP_TARGET} ${_HDRS} src/LTC681xBus.cpp - src/LTC681xChainBus.cpp + src/LTC681xChainBus.tpp src/LTC681xParallelBus.cpp ) target_include_directories(${APP_TARGET} PUBLIC include) diff --git a/include/LTC681xChainBus.h b/include/LTC681xChainBus.h index b9ef6c6..f6277f8 100644 --- a/include/LTC681xChainBus.h +++ b/include/LTC681xChainBus.h @@ -5,7 +5,7 @@ #include "LTC681xBus.h" -template +template class LTC681xChainBus : public LTC681xBus { public: LTC681xChainBus(SPI* spiDriver) : m_spiDriver(spiDriver) {}; @@ -21,3 +21,6 @@ class LTC681xChainBus : public LTC681xBus { private: SPI* m_spiDriver; }; + +// https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file +#include "../src/LTC681xChainBus.tpp" diff --git a/include/LTC681xCommand.h b/include/LTC681xCommand.h index e6a803b..8361e88 100644 --- a/include/LTC681xCommand.h +++ b/include/LTC681xCommand.h @@ -292,7 +292,7 @@ class StartCombinedCellVoltageGpioConversion : public LTC681xCommand { AdcMode adcMode; bool dischargePermitted; uint16_t toValue() const { - return 0x086F | ((uint16_t)adcMode << 7) | ((uint16_t)dischargePermitted << 4); + return 0x046F | ((uint16_t)adcMode << 7) | ((uint16_t)dischargePermitted << 4); } }; using ADCVAX = StartCombinedCellVoltageGpioConversion; @@ -347,3 +347,19 @@ class StartComm : public LTC681xCommand { uint16_t toValue() const { return 0x0723; } }; using STCOMM = StartComm; + +class MuteDischarge : public LTC681xCommand { + public: + uint16_t toValue() const { + return 0x28; + } +}; +using MUDIS = MuteDischarge; + +class UnmuteDischarge : public LTC681xCommand { + public: + uint16_t toValue() const { + return 0x29; + } +}; +using UMUDIS = UnmuteDischarge; \ No newline at end of file diff --git a/src/LTC681xChainBus.cpp b/src/LTC681xChainBus.tpp similarity index 88% rename from src/LTC681xChainBus.cpp rename to src/LTC681xChainBus.tpp index c51c1ac..d3866f4 100644 --- a/src/LTC681xChainBus.cpp +++ b/src/LTC681xChainBus.tpp @@ -6,7 +6,7 @@ #include "LTC681xBus.h" #include "mbed.h" -template +template LTC681xBus::LTC681xBusStatus LTC681xChainBus::WakeupBus() { // Pulse the CS once per chip, delaying the T_wake time between for(uint8_t i = 0; i < N_chips; i++) { @@ -18,7 +18,7 @@ LTC681xBus::LTC681xBusStatus LTC681xChainBus::WakeupBus() { return LTC681xBus::LTC681xBusStatus::Ok; } -template +template LTC681xBus::LTC681xBusStatus LTC681xChainBus::SendCommand(LTC681xBus::BusCommand cmd) { // // In daisy chain mode, to send a command we broadcast @@ -39,7 +39,7 @@ LTC681xBus::LTC681xBusStatus LTC681xChainBus::SendCommand(LTC681xBus::B return LTC681xBus::LTC681xBusStatus::Ok; } -template +template LTC681xBus::LTC681xBusStatus LTC681xChainBus::SendDataCommand(LTC681xBus::BusCommand cmd, uint8_t* data) { // // In daisy chain mode, to send a command with data, we first @@ -56,8 +56,9 @@ LTC681xBus::LTC681xBusStatus LTC681xChainBus::SendDataCommand(LTC681xBu // Create data value array uint8_t dataBytes[N_chips * 8]; + // Writing on a daisy chain means the last chip in the chain gets the first data sent - reverse here to keep the rest of the software sane for (uint8_t chip = 0; chip < N_chips; chip++) { - LTC681xBus::getDataBytes(dataBytes + (chip * 8), data + (chip * 6)); + LTC681xBus::getDataBytes(dataBytes + ((N_chips - 1 - chip) * 8), data + (chip * 6)); } // Grab the bus and send our command @@ -69,7 +70,7 @@ LTC681xBus::LTC681xBusStatus LTC681xChainBus::SendDataCommand(LTC681xBu return LTC681xBus::LTC681xBusStatus::Ok; } -template +template LTC681xBus::LTC681xBusStatus LTC681xChainBus::SendReadCommand(LTC681xBus::BusCommand cmd, uint8_t* data) { // // In daisy chain mode, to send a read command, we first send the @@ -112,7 +113,7 @@ LTC681xBus::LTC681xBusStatus LTC681xChainBus::SendReadCommand(LTC681xBu return LTC681xBus::LTC681xBusStatus::Ok; } -template +template LTC681xBus::LTC681xBusStatus LTC681xChainBus::SendCommandAndPoll(BusCommand cmd, unsigned int timeout) { // // In daisy chain mode, to send a command we broadcast @@ -132,7 +133,7 @@ LTC681xBus::LTC681xBusStatus LTC681xChainBus::SendCommandAndPoll(BusCom // Poll for ADC completion // Send initial N isoSPI clock pulses - for(unsigned int i = 0; i < N_chips / 8; i++) { + for(unsigned int i = 0; i <= (N_chips / 8); i++) { m_spiDriver->write(0xff); } @@ -145,7 +146,8 @@ LTC681xBus::LTC681xBusStatus LTC681xChainBus::SendCommandAndPoll(BusCom gotResponse = true; break; } else { - wait_us(LTC681x_POLL_DELAY); + // Use non-blocking wait since total conversion times are >1ms even for fastest conversion + ThisThread::sleep_for(1ms); } } m_spiDriver->deselect(); @@ -157,7 +159,7 @@ LTC681xBus::LTC681xBusStatus LTC681xChainBus::SendCommandAndPoll(BusCom } } -template +template LTC681xBus::LTC681xBusStatus LTC681xChainBus::PollAdcCompletion(BusCommand cmd, unsigned int timeout) { // // In daisy chain mode, to send a command we broadcast @@ -192,7 +194,8 @@ LTC681xBus::LTC681xBusStatus LTC681xChainBus::PollAdcCompletion(BusComm gotResponse = true; break; } else { - wait_us(LTC681x_POLL_DELAY); + // Use non-blocking wait since total conversion times are >1ms even for fastest conversion + ThisThread::sleep_for(1ms); } } m_spiDriver->deselect();