/* * BQ_Abstraction_Layer.c * * Created on: 29.01.2022 * Author: max */ #include "BQ_Abstraction_Layer.h" #include "BQ_Communication.h" #include "BQ_Register_Definitions.h" #include "stm32f4xx_hal.h" uint16_t cell_voltages[N_CELLS]; uint8_t bq_status; uint32_t lastmeasurementtime; void afe_init(UART_HandleTypeDef* uarthandle) { // Initialise underlying BQ Communication Functions init_BQCom(uarthandle); // Turn the AFE on off on to cycle a full reset afe_wakeup(); HAL_Delay(10); afe_shutdown(); HAL_Delay(100); afe_wakeup(); HAL_Delay(10); bq_status = BQ_INIT_PHASE; afe_config_communication(); afe_config_measurement_channels(); afe_config_gpios(); afe_activate_LED(); afe_init_fault_thresholds(); HAL_Delay(1000); afe_update_Checksum(); afe_clear_all_faults(); HAL_Delay(10); afe_check_faults(); } void afe_shutdown() { BQ_Write_Register(DEV_CNTRL, DEV_CNTRL_SIZE, 0x40); } void afe_wakeup() { HAL_GPIO_WritePin(WAKEUP_PORT, WAKEUP_PIN, GPIO_PIN_SET); HAL_Delay(1); HAL_GPIO_WritePin(WAKEUP_PORT, WAKEUP_PIN, GPIO_PIN_RESET); } void afe_measure() { uint8_t cellvoltagebuffer[2 * N_CELLS]; uint8_t retval = BQ_ReadMeasurements(cellvoltagebuffer, 2 * N_CELLS); lastmeasurementtime = HAL_GetTick(); if (retval == 0) { bq_status = BQ_ERROR; } else { for (int n = 0; n < N_CELLS; n++) { cell_voltages[N_CELLS - 1 - n] = (uint16_t)(cellvoltagebuffer[2 * n] << 8) + (uint16_t)cellvoltagebuffer[2 * n + 1]; } } } void afe_selftest() {} void afe_check_faults() { uint32_t faultflags = 0; BQ_Read_Register(FAULT_SUM, FAULT_SUM_SIZE, &faultflags); if (faultflags != 0) { bq_status = BQ_ERROR; } } void afe_clear_all_faults() { BQ_Write_Register(FAULT_SUM, FAULT_SUM_SIZE, 0xFFC0); // Clear all Faults bq_status = BQ_STDBY; HAL_Delay(1); afe_check_faults(); if (bq_status == BQ_STDBY) { bq_status = BQ_RDY; } } void afe_init_fault_thresholds() { BQ_Write_Register(FO_CTRL, FO_CTRL_SIZE, 0xC3C0); // Include UV Fault OV Fault COMM SYS CHIP GPI // Faults to Fault Output BQ_Write_Register(CELL_UV, CELL_UV_SIZE, (CELL_UV_THRESHOLD & 0x03)); BQ_Write_Register(CELL_OV, CELL_OV_SIZE, (CELL_OV_THRESHOLD & 0x03)); } void afe_update_Checksum() { uint32_t checksum = 0; BQ_Read_Register(CSUM_RSLT, CSUM_RSLT_SIZE, &checksum); BQ_Write_Register(CSUM, CSUM_SIZE, checksum); } void afe_config_measurement_channels() { uint16_t cellmask = 0b1111111111; uint32_t channelmask = cellmask << 16; BQ_Write_Register(NCHAN, NCHAN_SIZE, N_CELLS); uint32_t channels = 0b1111111111 << 16; BQ_Write_Register(CHANNELS, CHANNELS_SIZE, channels); BQ_Write_Register(OVERSMPL, OVERSMPL_SIZE, 0xFA); // Oversampling enabled with 4 samples as average } void afe_config_communication() { BQ_Write_Register( COMCONFIG, COMCONFIG_SIZE, (1 << 12) | (1 << 7)); // Enables UART Transceiver Diables Differential UART } void afe_config_gpios() { BQ_Write_Register(GPIO_DIR, GPIO_DIR_SIZE, 0x01); } void afe_activate_LED() { BQ_Write_Register(GPIO_OUT, GPIO_OUT_SIZE, 0x01); } void afe_config_balancing() { BQ_Write_Register(CBCONFIG, CBCONFIG_SIZE, 0x10); } void afe_balance_channels(uint16_t channelstobalance) { BQ_Write_Register(CBENBL, CBENBL_SIZE, channelstobalance); }