diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Abstraction.h b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Abstraction.h
index 9949d06..9b1bcaa 100755
--- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Abstraction.h
+++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_Abstraction.h
@@ -63,15 +63,14 @@ typedef struct {
 
 } Cell_Module;
 
-uint8_t amsReset();
+HAL_StatusTypeDef amsReset();
 
-uint8_t initAMS(SPI_HandleTypeDef* hspi);
-uint8_t amsWakeUp();
+HAL_StatusTypeDef initAMS(SPI_HandleTypeDef* hspi);
+HAL_StatusTypeDef amsWakeUp();
 
-uint8_t amsCellMeasurement(Cell_Module* module);
-uint8_t amsConfigCellMeasurement(uint8_t numberofChannels);
+HAL_StatusTypeDef amsCellMeasurement(Cell_Module* module);
 
-uint8_t amsAuxAndStatusMeasurement(Cell_Module* module);
+HAL_StatusTypeDef amsAuxAndStatusMeasurement(Cell_Module * module[static N_BMS]);
 uint8_t amsConfigAuxMeasurement(uint16_t Channels);
 
 uint8_t amsConfigGPIO(uint16_t gpios);
diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_LL_Driver.h b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_LL_Driver.h
index a893608..98f8280 100755
--- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_LL_Driver.h
+++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Inc/ADBMS_LL_Driver.h
@@ -50,7 +50,7 @@ static inline HAL_StatusTypeDef __writeCMD(uint16_t command, uint8_t * args, siz
 [[gnu::access(read_write, 2, 3), gnu::nonnull(2)]]
 HAL_StatusTypeDef readCMD(uint16_t command, uint8_t * buffer, size_t buflen);
 
-uint8_t pollCMD(uint16_t command);
+HAL_StatusTypeDef pollCMD(uint16_t command);
 
 
 void mcuAdbmsCSLow();
diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c
index 43ed55a..8d77df5 100755
--- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c
+++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_Abstraction.c
@@ -8,6 +8,7 @@
 #include "ADBMS_Abstraction.h"
 #include "ADBMS_CMD_MAKROS.h"
 #include "ADBMS_LL_Driver.h"
+#include "config_ADBMS6830.h"
 #include "swo_log.h"
 #include <stddef.h>
 
@@ -15,17 +16,17 @@ extern uint8_t numberofCells;
 
 #define CHECK_RETURN(x)                                                        \
   {                                                                            \
-    uint8_t status = x;                                                          \
+    uint8_t status = x;                                                        \
     if (status != 0)                                                           \
       return status;                                                           \
   }
 
-uint8_t amsReset() {
+HAL_StatusTypeDef amsReset() {
   amsWakeUp();
   readCMD(SRST, CMD_EMPTY_BUFFER, CMD_EMPTY_BUFFER_SIZE);
 
-  uint8_t buffer[CMD_BUFFER_SIZE(SID_GROUP_SIZE)] = {0};
-  CHECK_RETURN(readCMD(RDSID, buffer, CMD_BUFFER_SIZE(SID_GROUP_SIZE)));
+  uint8_t sidbuffer[CMD_BUFFER_SIZE(SID_GROUP_SIZE)] = {};
+  CHECK_RETURN(readCMD(RDSID, sidbuffer, CMD_BUFFER_SIZE(SID_GROUP_SIZE)));
 
   debug_log(LOG_LEVEL_INFO, "BMS reset complete\n");
 
@@ -34,7 +35,7 @@ uint8_t amsReset() {
     for (size_t i = 0; i < N_BMS; i++) {
       uint64_t id = 0;
       for (size_t j = 0; j < SID_GROUP_SIZE; j++) {
-        id |= buffer[BUFFER_BMS_OFFSET(i, SID_GROUP_SIZE) + j] << (j * 8);
+        id |= sidbuffer[BUFFER_BMS_OFFSET(i, SID_GROUP_SIZE) + j] << (j * 8);
       }
       debug_log_cont(LOG_LEVEL_INFO, "0x%llx ", id);
     }
@@ -46,94 +47,110 @@ uint8_t amsReset() {
   amsStopBalancing();
   amsConfigOverUnderVoltage(DEFAULT_OV, DEFAULT_UV);
 
-  CHECK_RETURN(writeCMD(CLRFLAG, buffer, 6)); //clear flags,
-  CHECK_RETURN(writeCMD(CLOVUV, buffer, 6));  //OVUV flags
-  CHECK_RETURN(writeCMD(ADCV | ADCV_CONT | ADCV_RD, NULL, 0)); //start continuous cell voltage measurement with redundancy
-  CHECK_RETURN(writeCMD(ADAX | ADAX_CONV_ALL, NULL, 0)); //start aux measurement
+  uint8_t flagsbuffer[CMD_BUFFER_SIZE(6)] = {[0 ... CMD_BUFFER_SIZE(6) - 1] = 0xFF}; //technically not all 6 bytes are used, but it's easier to just set all to 0xFF
+                                                                                     //see page 27 of the datasheet for the memory map
+
+  CHECK_RETURN(writeCMD(CLRFLAG, flagsbuffer, 6)); //clear flags,
+  CHECK_RETURN(writeCMD(CLOVUV, flagsbuffer, 6));  //OVUV flags
+  CHECK_RETURN(writeCMD(ADCV | ADCV_CONT | ADCV_RD, flagsbuffer, 0)); //start continuous cell voltage measurement with redundancy
+  CHECK_RETURN(writeCMD(ADAX | ADAX_CONV_ALL, flagsbuffer, 0)); //start aux measurement
 
   return 0;
 }
 
-uint8_t initAMS(SPI_HandleTypeDef* hspi) {
+HAL_StatusTypeDef initAMS(SPI_HandleTypeDef* hspi) {
   adbmsDriverInit(hspi);
   return amsReset();
 }
 
-uint8_t amsWakeUp() {
+HAL_StatusTypeDef amsWakeUp() {
   uint8_t buffer[CMD_BUFFER_SIZE(CFG_GROUP_A_SIZE)] = {0};
   return readCMD(RDCFGA, buffer, CMD_BUFFER_SIZE(CFG_GROUP_A_SIZE));
 }
 
-uint8_t amsCellMeasurement(Cell_Module* module) {
+HAL_StatusTypeDef amsCellMeasurement(Cell_Module* module) {
   #warning check conversion counter to ensure that continous conversion has not been stopped
   #warning check for OW conditions: ADSV | ADSV_OW_0 / ADSV_OW_1
   return amsReadCellVoltages(module);
 }
 
-uint8_t amsAuxAndStatusMeasurement(Cell_Module* module) {
-  uint8_t rxbuf[AUX_GROUP_A_SIZE] = {};
+HAL_StatusTypeDef amsAuxAndStatusMeasurement(Cell_Module * module[static N_BMS]) {
+  uint8_t rxbuf[CMD_BUFFER_SIZE(STATUS_GROUP_C_SIZE)] = {};
 
-  CHECK_RETURN(readCMD(RDSTATC, rxbuf, STATUS_GROUP_C_SIZE));
-
-  module->status.CS_FLT = rxbuf[0] | (rxbuf[1] << 8);
-  module->status.CCTS   = rxbuf[2] | (rxbuf[3] << 8);
-  module->status.VA_OV  = (rxbuf[4] >> 7) & 0x01;
-  module->status.VA_UV  = (rxbuf[4] >> 6) & 0x01;
-  module->status.VD_OV  = (rxbuf[4] >> 5) & 0x01;
-  module->status.VD_UV  = (rxbuf[4] >> 4) & 0x01;
-  module->status.CED    = (rxbuf[4] >> 3) & 0x01;
-  module->status.CMED   = (rxbuf[4] >> 2) & 0x01;
-  module->status.SED    = (rxbuf[4] >> 1) & 0x01;
-  module->status.SMED   = (rxbuf[4] >> 0) & 0x01;
-  module->status.VDEL   = (rxbuf[5] >> 7) & 0x01;
-  module->status.VDE    = (rxbuf[5] >> 6) & 0x01;
-  module->status.COMPARE= (rxbuf[5] >> 5) & 0x01;
-  module->status.SPIFLT = (rxbuf[5] >> 4) & 0x01;
-  module->status.SLEEP  = (rxbuf[5] >> 3) & 0x01;
-  module->status.THSD   = (rxbuf[5] >> 2) & 0x01;
-  module->status.TMODCHK= (rxbuf[5] >> 1) & 0x01;
-  module->status.OSCCHK = (rxbuf[5] >> 0) & 0x01;
-
-  if (pollCMD(PLAUX) == 0x0) { //TODO: check for SPI fault
-    return 0; // aux ADC data not ready
+  CHECK_RETURN(readCMD(RDSTATC, rxbuf, sizeof rxbuf));
+  for (size_t i = 0; i < N_BMS; i++) {
+    size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_C_SIZE);
+    module[i]->status.CS_FLT = rxbuf[offset + 0] | (rxbuf[offset + 1] << 8);
+    module[i]->status.CCTS   = rxbuf[offset + 2] | (rxbuf[offset + 3] << 8);
+    module[i]->status.VA_OV  = (rxbuf[offset + 4] >> 7) & 0x01;
+    module[i]->status.VA_UV  = (rxbuf[offset + 4] >> 6) & 0x01;
+    module[i]->status.VD_OV  = (rxbuf[offset + 4] >> 5) & 0x01;
+    module[i]->status.VD_UV  = (rxbuf[offset + 4] >> 4) & 0x01;
+    module[i]->status.CED    = (rxbuf[offset + 4] >> 3) & 0x01;
+    module[i]->status.CMED   = (rxbuf[offset + 4] >> 2) & 0x01;
+    module[i]->status.SED    = (rxbuf[offset + 4] >> 1) & 0x01;
+    module[i]->status.SMED   = (rxbuf[offset + 4] >> 0) & 0x01;
+    module[i]->status.VDEL   = (rxbuf[offset + 5] >> 7) & 0x01;
+    module[i]->status.VDE    = (rxbuf[offset + 5] >> 6) & 0x01;
+    module[i]->status.COMPARE= (rxbuf[offset + 5] >> 5) & 0x01;
+    module[i]->status.SPIFLT = (rxbuf[offset + 5] >> 4) & 0x01;
+    module[i]->status.SLEEP  = (rxbuf[offset + 5] >> 3) & 0x01;
+    module[i]->status.THSD   = (rxbuf[offset + 5] >> 2) & 0x01;
+    module[i]->status.TMODCHK= (rxbuf[offset + 5] >> 1) & 0x01;
+    module[i]->status.OSCCHK = (rxbuf[offset + 5] >> 0) & 0x01;
   }
 
-  CHECK_RETURN(readCMD(RDAUXA, rxbuf, AUX_GROUP_A_SIZE));
+  if (pollCMD(PLAUX) == HAL_BUSY) {
+    return HAL_BUSY;
+  }
 
-  module->auxVoltages[0] = mV_from_ADBMS6830(rxbuf[0] | (rxbuf[1] << 8));
-  module->auxVoltages[1] = mV_from_ADBMS6830(rxbuf[2] | (rxbuf[3] << 8));
-  module->auxVoltages[2] = mV_from_ADBMS6830(rxbuf[4] | (rxbuf[5] << 8));
+  CHECK_RETURN(readCMD(RDAUXA, rxbuf, CMD_BUFFER_SIZE(AUX_GROUP_A_SIZE))); //STATUS_GROUP_C_SIZE is the same as AUX_GROUP_A_SIZE, so we can reuse the buffer
+  for (size_t i = 0; i < N_BMS; i++) {
+    size_t offset = BUFFER_BMS_OFFSET(i, AUX_GROUP_A_SIZE);
+    module[i]->auxVoltages[0] = mV_from_ADBMS6830(rxbuf[offset + 0] | (rxbuf[offset + 1] << 8));
+    module[i]->auxVoltages[1] = mV_from_ADBMS6830(rxbuf[offset + 2] | (rxbuf[offset + 3] << 8));
+    module[i]->auxVoltages[2] = mV_from_ADBMS6830(rxbuf[offset + 4] | (rxbuf[offset + 5] << 8));
+  }
 
-  CHECK_RETURN(readCMD(RDAUXB, rxbuf, AUX_GROUP_A_SIZE));
+  CHECK_RETURN(readCMD(RDAUXB, rxbuf, CMD_BUFFER_SIZE(AUX_GROUP_B_SIZE)));
+  for (size_t i = 0; i < N_BMS; i++) {
+    size_t offset = BUFFER_BMS_OFFSET(i, AUX_GROUP_B_SIZE);
+    module[i]->auxVoltages[3] = mV_from_ADBMS6830(rxbuf[offset + 0] | (rxbuf[offset + 1] << 8));
+    module[i]->auxVoltages[4] = mV_from_ADBMS6830(rxbuf[offset + 2] | (rxbuf[offset + 3] << 8));
+    module[i]->auxVoltages[5] = mV_from_ADBMS6830(rxbuf[offset + 4] | (rxbuf[offset + 5] << 8));
+  }
 
-  module->auxVoltages[3] = mV_from_ADBMS6830(rxbuf[0] | (rxbuf[1] << 8));
-  module->auxVoltages[4] = mV_from_ADBMS6830(rxbuf[2] | (rxbuf[3] << 8));
-  module->auxVoltages[5] = mV_from_ADBMS6830(rxbuf[4] | (rxbuf[5] << 8));
+  CHECK_RETURN(readCMD(RDAUXC, rxbuf, CMD_BUFFER_SIZE(AUX_GROUP_C_SIZE)));
+  for (size_t i = 0; i < N_BMS; i++) {
+    size_t offset = BUFFER_BMS_OFFSET(i, AUX_GROUP_C_SIZE);
+    module[i]->auxVoltages[6] = mV_from_ADBMS6830(rxbuf[offset + 0] | (rxbuf[offset + 1] << 8));
+    module[i]->auxVoltages[7] = mV_from_ADBMS6830(rxbuf[offset + 2] | (rxbuf[offset + 3] << 8));
+    module[i]->auxVoltages[8] = mV_from_ADBMS6830(rxbuf[offset + 4] | (rxbuf[offset + 5] << 8));
+  }
 
-  CHECK_RETURN(readCMD(RDAUXC, rxbuf, AUX_GROUP_A_SIZE));
+  CHECK_RETURN(readCMD(RDAUXD, rxbuf, CMD_BUFFER_SIZE(AUX_GROUP_D_SIZE)));
+  for (size_t i = 0; i < N_BMS; i++) {
+    size_t offset = BUFFER_BMS_OFFSET(i, AUX_GROUP_D_SIZE);
+    module[i]->auxVoltages[9] = mV_from_ADBMS6830(rxbuf[offset + 0] | (rxbuf[offset + 1] << 8));
+  }
 
-  module->auxVoltages[6] = mV_from_ADBMS6830(rxbuf[0] | (rxbuf[1] << 8));
-  module->auxVoltages[7] = mV_from_ADBMS6830(rxbuf[2] | (rxbuf[3] << 8));
-  module->auxVoltages[8] = mV_from_ADBMS6830(rxbuf[4] | (rxbuf[5] << 8));
+  CHECK_RETURN(readCMD(RDSTATA, rxbuf, CMD_BUFFER_SIZE(STATUS_GROUP_A_SIZE)));
+  for (size_t i = 0; i < N_BMS; i++) {
+    size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_A_SIZE);
+    module[i]->internalDieTemp = rxbuf[offset + 2] | (rxbuf[offset + 3] << 8);
+  }
 
-  CHECK_RETURN(readCMD(RDAUXD, rxbuf, AUX_GROUP_A_SIZE));
+  CHECK_RETURN(readCMD(RDSTATB, rxbuf, CMD_BUFFER_SIZE(STATUS_GROUP_B_SIZE)));
+  for (size_t i = 0; i < N_BMS; i++) {
+    size_t offset = BUFFER_BMS_OFFSET(i, STATUS_GROUP_B_SIZE);
+    module[i]->digitalSupplyVoltage = mV_from_ADBMS6830(rxbuf[offset + 0] | (rxbuf[offset + 1] << 8));
+    module[i]->analogSupplyVoltage  = mV_from_ADBMS6830(rxbuf[offset + 2] | (rxbuf[offset + 3] << 8));
+    module[i]->refVoltage           = mV_from_ADBMS6830(rxbuf[offset + 4] | (rxbuf[offset + 5] << 8));
+  }
 
-  module->auxVoltages[9] = mV_from_ADBMS6830(rxbuf[0] | (rxbuf[1] << 8));
+  CHECK_RETURN(writeCMD(ADAX | ADAX_CONV_ALL, rxbuf, 0)); //start aux conversion for next iteration
 
-  uint8_t rxbuffer[STATUS_GROUP_A_SIZE];
-
-  CHECK_RETURN(readCMD(RDSTATA, rxbuffer, STATUS_GROUP_A_SIZE));
-
-  module->internalDieTemp = rxbuffer[2] | (rxbuffer[3] << 8);
-
-  CHECK_RETURN(readCMD(RDSTATB, rxbuffer, STATUS_GROUP_B_SIZE));
-  module->digitalSupplyVoltage = mV_from_ADBMS6830(rxbuffer[0] | (rxbuffer[1] << 8));
-  module->analogSupplyVoltage  = mV_from_ADBMS6830(rxbuffer[2] | (rxbuffer[3] << 8));
-  module->refVoltage           = mV_from_ADBMS6830(rxbuffer[4] | (rxbuffer[5] << 8));
-
-  CHECK_RETURN(writeCMD(ADAX | ADAX_CONV_ALL, NULL, 0)); //start aux measurement for next cycle
-
-  return 0;
+  return HAL_OK;
 }
 
 uint8_t amsConfigBalancing(uint32_t channels, uint8_t dutyCycle) {
diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c
index 84fe45d..fdad225 100755
--- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c
+++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Core/Src/ADBMS_LL_Driver.c
@@ -331,23 +331,21 @@ HAL_StatusTypeDef readCMD(uint16_t command, uint8_t * buffer, size_t buflen) {
 }
 
 //check poll command - no data PEC sent back
-uint8_t pollCMD(uint16_t command) {
-  uint8_t txbuffer[5] = {};
-  uint8_t rxbuffer[5] = {};
+HAL_StatusTypeDef pollCMD(uint16_t command) {
+  uint8_t buffer[4 + (N_BMS * 2) + 1] = {}; //poll is only valid after 2 * N_BMS clock cycles (datasheet page 55)
+                                            //being conservative and adding 1 byte for the poll response
 
-  txbuffer[0] = (command >> 8) & 0xFF;
-  txbuffer[1] = (command)&0xFF;
-  calculateCommandPEC(txbuffer, 4);
+  buffer[0] = (command >> 8) & 0xFF;
+  buffer[1] = (command) & 0xFF;
+  calculateCommandPEC(buffer, 4);
 
   mcuAdbmsCSLow();
-  uint8_t status = mcuSPITransmitReceive(rxbuffer, txbuffer, 5);
+  HAL_StatusTypeDef status = mcuSPITransmitReceive(buffer, buffer, 4 + (N_BMS * 2) + 1);
   mcuAdbmsCSHigh();
 
-  if (status != 0) {
-    return status;
-  }
+  if (status != HAL_OK) return status;
 
-  return rxbuffer[4]; //last byte will be poll response
+  return ((buffer[4 + (N_BMS * 2)] & 0x0F) == 0x0) ? HAL_BUSY : HAL_OK; //SDO goes high when data is ready
 }
 
 void mcuAdbmsCSLow() {