cc_cv_charging.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include "cc_cv_charging.h"
  2. #include "battery.h"
  3. #include "dac.h"
  4. #include "adc.h"
  5. #include "ti/devices/msp/m0p/mspm0g350x.h"
  6. #include "ti/driverlib/dl_gpio.h"
  7. #include <stdio.h>
  8. #define MAX_VOLTAGE_MV (4200)
  9. #define MIN_VOLTAGE_MV (3000)
  10. #define CC_CURRENT_LIMIT_MA (500)
  11. #define CUTOFF_CURRENT_MA (50)
  12. #define MAX_CYCLES (500)
  13. // if the battery is deeply discharged then 50mA of trickle charge is given for a set timer
  14. #define TRICKLE_CHARGE_CURRENT_MA (50)
  15. #define TRICKLE_CHARGE_VOLTAGE_MV (2100)
  16. #define TRICKLE_CHARGE_TIMEOUT_MS (5000) //5 mseconds
  17. //Pre Charge
  18. #define BATTERY_CAPACITY_MAH (2000)
  19. #define PRE_CHARGE_CURRENT_MA (BATTERY_CAPACITY_MAH/ 10)
  20. static ChargingState charging_state= STATE_PRE_CHARGE;
  21. static uint16_t cycle_count= 0;
  22. static uint32_t pre_charge_start_time= 0;
  23. //batt_voltage and current as stored from ADC
  24. void CC_CV_UpdateChargingState(uint8_t slot_id){
  25. uint16_t batt_voltage= batteries[slot_id].voltage;
  26. int16_t batt_current= batteries[slot_id].current;
  27. static uint16_t trickle_timer= 0;
  28. if(batt_voltage < TRICKLE_CHARGE_VOLTAGE_MV){
  29. charging_state= STATE_TRICKLE_CHARGE;
  30. trickle_timer= 0;
  31. }
  32. else if(charging_state== STATE_TRICKLE_CHARGE){
  33. trickle_timer ++;
  34. if(trickle_timer >= TRICKLE_CHARGE_TIMEOUT_MS){
  35. charging_state = STATE_ERROR;
  36. }
  37. }
  38. else if(batt_voltage < MIN_VOLTAGE_MV){
  39. charging_state= STATE_PRE_CHARGE;
  40. }
  41. else if(batt_voltage >= MIN_VOLTAGE_MV && batt_voltage < MAX_VOLTAGE_MV - BATTERY_THRESHOLD){
  42. charging_state= STATE_CC_CHARGING;
  43. }
  44. else if(batt_voltage >= MAX_VOLTAGE_MV - BATTERY_THRESHOLD){
  45. charging_state= STATE_CV_CHARGING;
  46. }
  47. else if(charging_state == STATE_CV_CHARGING && batt_current <= CUTOFF_CURRENT_MA + BATTERY_THRESHOLD){
  48. if(cycle_count < MAX_CYCLES){
  49. charging_state= STATE_DISCHARGING;
  50. }
  51. else{
  52. charging_state = STATE_FINAL_DISCHARGE;
  53. }
  54. }
  55. else if(charging_state == STATE_DISCHARGING && batt_voltage <= MIN_VOLTAGE_MV + BATTERY_THRESHOLD) {
  56. charging_state= STATE_CC_CHARGING;
  57. }
  58. else{
  59. charging_state= STATE_ERROR;
  60. }
  61. }
  62. /*
  63. Function for Battery Charging and Discharging:
  64. Trickle Charge: Only used when the battery voltage < ~2.1 V.
  65. - In this state, the batteries internal protection may have been previously disconnected.
  66. Pre Charge: Once the battery is in discharged state, pre-charging begins.
  67. - Starts charging safely with a typically low current C/10
  68. Constant Current: Continues until the battery voltage has reached the "full" or floating voltage level
  69. Constant Voltage: CV volatge starts once the maximum voltage threshold is obtained
  70. */
  71. void CC_CV_ControlCharging(uint8_t slot_id){
  72. CC_CV_UpdateChargingState(slot_id);
  73. uint16_t batt_voltage= batteries[slot_id].voltage;
  74. int16_t batt_current= batteries[slot_id].current;
  75. switch(charging_state){
  76. case STATE_TRICKLE_CHARGE:
  77. DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB0_PIN);
  78. //GPIO_setConfig(GPIO_Battery_Charging_PIN_PB0_PIN , GPIO_CFG_OUT_STD| GPIO_CFG_OUT_HIGH | GPIO_Battery_Charging_PIN_PB0_IOMUX);
  79. DAC_fastWrite(TRICKLE_CHARGE_CURRENT_MA);
  80. printf("[CC-CV] Trickle Charging: Slot %d at %d mA.\n", slot_id, TRICKLE_CHARGE_CURRENT_MA);
  81. break;
  82. case STATE_PRE_CHARGE:
  83. DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB0_PIN);
  84. //GPIO_setConfig(GPIO_Battery_Charging_PIN_PB0_PIN , GPIO_CFG_OUT_STD| GPIO_CFG_OUT_HIGH | GPIO_Battery_Charging_PIN_PB0_IOMUX);
  85. DAC_fastWrite(PRE_CHARGE_CURRENT_MA);
  86. printf("[CC-CV] Pre Charging: Slot %d at %d mA.\n", slot_id, PRE_CHARGE_CURRENT_MA);
  87. break;
  88. case STATE_CC_CHARGING:
  89. DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB0_PIN);
  90. //GPIO_setConfig(GPIO_Battery_Charging_PIN_PB0_PIN , GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH | GPIO_Battery_Charging_PIN_PB0_IOMUX);
  91. DAC_fastWrite(CC_CURRENT_LIMIT_MA);
  92. printf("[CC-CV] CC Charging: Slot %d at %d mA.\n", slot_id, CC_CURRENT_LIMIT_MA);
  93. break;
  94. case STATE_CV_CHARGING:
  95. DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB0_PIN);
  96. //GPIO_setConfig(GPIO_Battery_Charging_PIN_PB0_PIN , GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH | GPIO_Battery_Charging_PIN_PB0_IOMUX);
  97. DAC_fastWrite(CUTOFF_CURRENT_MA);
  98. printf("[CC-CV] CV Charging: Slot %d at %d mA.\n", slot_id, CUTOFF_CURRENT_MA);
  99. break;
  100. case STATE_DISCHARGING:
  101. DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB0_PIN);
  102. DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Discharging_PIN_PB8_PIN);
  103. //GPIO_setConfig(GPIO_Battery_Charging_PIN_PB0_PIN , GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH | GPIO_Battery_Discharging_PIN_PB8_IOMUX);
  104. DAC_fastWrite(batt_voltage);
  105. printf("[CC-CV] Discharging: Slot %d at %d mA.\n", slot_id, batt_voltage);
  106. break;
  107. case STATE_FINAL_DISCHARGE:
  108. DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB0_PIN);
  109. DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB8_PIN);
  110. printf("[CC-CV] Final Discharge: Slot %d..\n", slot_id);
  111. DAC_fastWrite(0);
  112. case STATE_ERROR:
  113. DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB0_PIN);
  114. DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB8_PIN);
  115. printf("[CC-CV] Error: Slot %d.\n", slot_id);
  116. default:
  117. break;
  118. }
  119. }