.. _program_listing_file_mainboard_Src_bal.c: Program Listing for File bal.c ============================== |exhale_lsh| :ref:`Return to documentation for file ` (``mainboard/Src/bal.c``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "bal.h" #include #ifndef max #define max(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) #endif uint8_t _max_index(uint16_t data[], size_t count) { uint8_t max = 0; for (uint8_t i = 0; i < count; i++) { if (data[i] > data[max]) max = i; } return max; } uint16_t _min_index(voltage_t data[], size_t count) { uint16_t min_value_index = 0; for (uint16_t i = 0; i < count; i++) { if (data[i] < data[min_value_index]) min_value_index = i; } return min_value_index; } void _bal_hateville_solution(uint16_t DP[], uint16_t i, uint16_t out[], uint16_t *out_index) { if (i == 0) { return; } else if (i == 1) { if (DP[1] > 0) { out[(*out_index)++] = 0; } return; } else if (DP[i] == DP[i - 1]) { _bal_hateville_solution(DP, i - 1, out, out_index); return; } else { _bal_hateville_solution(DP, i - 2, out, out_index); out[(*out_index)++] = i - 1; return; } } uint16_t _bal_hateville(uint16_t D[], uint16_t count, uint16_t solution[]) { uint16_t DP[count + 1]; DP[0] = 0; DP[1] = D[0]; for (uint16_t i = 2; i < count + 1; i++) { DP[i] = max(DP[i - 1], DP[i - 2] + D[i - 1]); } uint16_t out_index = 0; _bal_hateville_solution(DP, count, solution, &out_index); return out_index; } /* @section Public functions */ uint16_t bal_get_cells_to_discharge(voltage_t volts[], uint16_t count, voltage_t threshold, uint16_t cells[]) { voltage_t imbalance[count]; uint16_t len = bal_compute_imbalance(volts, count, threshold, imbalance); if (len == 0) { return false; } return bal_exclude_neighbors(imbalance, len, cells); } uint16_t bal_compute_imbalance(voltage_t volts[], uint16_t count, voltage_t threshold, uint16_t cells[]) { uint16_t indexes = 0; uint16_t min_index = _min_index(volts, count); for (uint16_t i = 0; i < count; i++) { cells[i] = max(0, volts[i] - (volts[min_index] + threshold)); if (cells[i] > 0) { indexes++; } } return indexes; } uint16_t bal_exclude_neighbors(uint16_t data[], uint16_t count, uint16_t cells[]) { for (uint16_t i = 0; i < PACK_CELL_COUNT; i++) { cells[i] = BAL_NULL_INDEX; } return _bal_hateville(data, PACK_CELL_COUNT, cells); }