|
@@ -43,12 +43,31 @@ typedef enum chrgr_state {
|
|
|
Error
|
|
|
} charger_state_t;
|
|
|
|
|
|
-typedef struct {
|
|
|
+typedef struct timer {
|
|
|
uint8_t hh;
|
|
|
uint8_t mm;
|
|
|
uint8_t ss;
|
|
|
} time_cnt_t;
|
|
|
|
|
|
+typedef struct accum_profile {
|
|
|
+ char * Chemistry;
|
|
|
+ char * VoltageNominal;
|
|
|
+ uint32_t Capacity_mAh;
|
|
|
+ uint32_t VoltageMax_mv;
|
|
|
+ uint32_t VoltageDechMin_mv;
|
|
|
+ uint32_t CurrentMax_mA;
|
|
|
+ uint32_t CurrentChrgMin_mA;
|
|
|
+ time_cnt_t TimeChargeMax;
|
|
|
+ char * Description;
|
|
|
+} accum_profile_t;
|
|
|
+
|
|
|
+#define ACCUM_PRIFILE_NUM 3
|
|
|
+accum_profile_t Profile[ACCUM_PRIFILE_NUM] = {
|
|
|
+ {"SLA", "12V", 12000, 15000, 10500, 3600, 240, {24,0,0}, "GP12120"},
|
|
|
+ {"LiIon", "1S1", 3200, 4200, 2500, 1625, 65, {4,0,0}, "NCR18650B"},
|
|
|
+ {"LiIon", "1S2", 2600, 4200, 2750, 1300, 130, {3,0,0}, "ICR18650-26F"}
|
|
|
+};
|
|
|
+
|
|
|
// types and description of accums - SLA, LiIon
|
|
|
|
|
|
// variants and description of voltaged accroding to cemistry type - 6/12V, 1-4S
|
|
@@ -92,6 +111,7 @@ static void btn1_handler(const button_state_t);
|
|
|
static void btn2_handler(const button_state_t);
|
|
|
static void btn3_handler(const button_state_t);
|
|
|
static void btn4_handler(const button_state_t);
|
|
|
+static void show_MenuItem(const int item);
|
|
|
|
|
|
/* Private variables */
|
|
|
static binary_semaphore_t ina_bsem, charger_bsem;
|
|
@@ -99,7 +119,8 @@ static virtual_timer_t mode_vt;
|
|
|
static event_source_t ina_all_event, ina_bus_event;
|
|
|
static event_source_t chrgr_st_event, time_event;
|
|
|
static charger_state_t charger_State;
|
|
|
-static ina3221_ch_t current_Channel;
|
|
|
+static ina3221_ch_t charger_Channel;
|
|
|
+static int charger_Profile = 0;
|
|
|
static uint32_t Current;
|
|
|
static uint32_t Voltage;
|
|
|
static uint32_t Power, Capacity_I=0, Capacity_P=0;
|
|
@@ -276,7 +297,7 @@ int main(void) {
|
|
|
|
|
|
/* Init charger module */
|
|
|
charger_State = Stop;
|
|
|
- current_Channel = INA3221_CH1;
|
|
|
+ charger_Channel = INA3221_CH1;
|
|
|
|
|
|
event_listener_t el0, el1, el2, el3;
|
|
|
|
|
@@ -304,8 +325,6 @@ int main(void) {
|
|
|
events = chEvtWaitAny(ALL_EVENTS);
|
|
|
|
|
|
if (events & INA_ALL_VALUSE) {
|
|
|
- /* place to control curren/voltage in charge/decharge modes */
|
|
|
-
|
|
|
tmp1 = Voltage / 1000;
|
|
|
tmp2 = Voltage % 1000;
|
|
|
chsnprintf(buf, 11, "U:%2d.%03uV", tmp1, tmp2);
|
|
@@ -332,6 +351,43 @@ int main(void) {
|
|
|
tmp2 = tmp0 % 1000;
|
|
|
chsnprintf(buf, 13, "CP:%2d.%03uWh", tmp1, tmp2);
|
|
|
gdispFillStringBox(160, 183, 158, 29, buf, font2, Red, Gray, gJustifyLeft);
|
|
|
+
|
|
|
+ /* Check charge/decharge conditions */
|
|
|
+ switch (charger_State) {
|
|
|
+ case Charge1:
|
|
|
+ case Charge2:
|
|
|
+ if (Profile[charger_Profile].VoltageMax_mv < Voltage) {
|
|
|
+ gwinPrintf(GW1, "Overvoltage detected!\n");
|
|
|
+ charger_State = Error;
|
|
|
+ events |= CHRGR_ST_CHANGE;
|
|
|
+ }
|
|
|
+ if (Profile[charger_Profile].CurrentMax_mA < Current) {
|
|
|
+ gwinPrintf(GW1, "Overcurrent detected!\n");
|
|
|
+ charger_State = Error;
|
|
|
+ events |= CHRGR_ST_CHANGE;
|
|
|
+ }
|
|
|
+ if (Profile[charger_Profile].CurrentChrgMin_mA > Current) {
|
|
|
+ gwinPrintf(GW1, "Charged Successful.\n");
|
|
|
+ if (charger_State == Charge1) {
|
|
|
+ charger_State = Pause1;
|
|
|
+ } else {
|
|
|
+ charger_State = Stop;
|
|
|
+ }
|
|
|
+ events |= CHRGR_ST_CHANGE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case Decharge:
|
|
|
+ if (Profile[charger_Profile].VoltageDechMin_mv > Voltage) {
|
|
|
+ gwinPrintf(GW1, "Decharge finished.\n");
|
|
|
+ charger_State = Pause2;
|
|
|
+ events |= CHRGR_ST_CHANGE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (events & INA_BUS_VALUES) {
|
|
@@ -339,6 +395,7 @@ int main(void) {
|
|
|
tmp2 = Voltage % 1000;
|
|
|
chsnprintf(buf, 11, "U:%2d.%03uV", tmp1, tmp2);
|
|
|
gdispFillStringBox(1, 123, 158, 29, buf, font2, Red, Gray, gJustifyLeft);
|
|
|
+ /* here should control processes time ? */
|
|
|
}
|
|
|
|
|
|
if (events & CHRGR_ST_CHANGE) {
|
|
@@ -458,12 +515,10 @@ static void prepare_Screen(void) {
|
|
|
gdispFillArea(1, 1, 78, 121, Blue); // text area
|
|
|
|
|
|
/* print text to top-left area */
|
|
|
- gdispDrawStringBox(1, 1, 78, 15, "[1] ch.1 ", font1, Yellow, gJustifyLeft);
|
|
|
- gdispDrawStringBox(1, 16, 78, 15, " - A ", font1, Yellow, gJustifyLeft);
|
|
|
- gdispDrawStringBox(1, 31, 78, 15, "[2] SLA", font1, Yellow, gJustifyLeft);
|
|
|
- gdispDrawStringBox(1, 46, 78, 15, " - 12V", font1, Yellow, gJustifyLeft);
|
|
|
- gdispDrawStringBox(1, 61, 78, 15, "[3] current", font1, Yellow, gJustifyLeft);
|
|
|
- gdispDrawStringBox(1, 76, 78, 15, " - 1A", font1, Yellow, gJustifyLeft);
|
|
|
+ show_MenuItem(1);
|
|
|
+ show_MenuItem(2);
|
|
|
+ gdispDrawStringBox(1, 61, 78, 15, "[3] show ch", font1, Yellow, gJustifyLeft);
|
|
|
+ gdispDrawStringBox(1, 76, 78, 15, "dech results", font1, Yellow, gJustifyLeft);
|
|
|
gdispDrawStringBox(1, 91, 78, 15, "[4] start", font1, Yellow, gJustifyLeft);
|
|
|
// gdispDrawStringBox(1, 106, 78, 15, " ", font1, Yellow, gJustifyLeft);
|
|
|
|
|
@@ -496,54 +551,56 @@ static void btn1_handler(button_state_t state) {
|
|
|
gwinPrintf(GW1, "Button 1 pressed\n");
|
|
|
|
|
|
if (charger_State == Stop) {
|
|
|
- switch (current_Channel)
|
|
|
+ switch (charger_Channel)
|
|
|
{
|
|
|
case INA3221_CH1:
|
|
|
- current_Channel = INA3221_CH2;
|
|
|
+ charger_Channel = INA3221_CH2;
|
|
|
break;
|
|
|
case INA3221_CH2:
|
|
|
- current_Channel = INA3221_CH3;
|
|
|
+ charger_Channel = INA3221_CH3;
|
|
|
break;
|
|
|
case INA3221_CH3:
|
|
|
- current_Channel = INA3221_CH1;
|
|
|
+ charger_Channel = INA3221_CH1;
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
- current_Channel = INA3221_CH1;
|
|
|
+ charger_Channel = INA3221_CH1;
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
- int tmp = (int)current_Channel + 1;
|
|
|
- gwinPrintf(GW1, "Channel #%u selected.\n", tmp);
|
|
|
-
|
|
|
- char buf[16];
|
|
|
- chsnprintf(buf, 10, "[1] ch.%u", tmp);
|
|
|
- gdispFillStringBox(1, 1, 78, 15, buf, font1, Yellow, Blue, gJustifyLeft);
|
|
|
-
|
|
|
- chsnprintf(buf, 12, " - %2uA ", charger_Channels[current_Channel].max_current/1000);
|
|
|
- gdispFillStringBox(1, 16, 78, 15, buf, font1, Yellow, Blue, gJustifyLeft);
|
|
|
+ show_MenuItem(1);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void btn2_handler(button_state_t state) {
|
|
|
if (state == BTN_st_Pressed) {
|
|
|
- gwinPrintf(GW1, "Button 2 pressed\n");
|
|
|
- Capacity_I = ch_Capacity_I;
|
|
|
- Capacity_P = ch_Capacity_P;
|
|
|
- Timer = chTimer;
|
|
|
-
|
|
|
- chEvtBroadcast(&ina_all_event);
|
|
|
- chEvtBroadcast(&time_event);
|
|
|
+ charger_Profile ++;
|
|
|
+ if (charger_Profile >= ACCUM_PRIFILE_NUM) {
|
|
|
+ charger_Profile = 0;
|
|
|
+ }
|
|
|
+ show_MenuItem(2);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void btn3_handler(button_state_t state) {
|
|
|
+ static int s = 0;
|
|
|
+
|
|
|
if (state == BTN_st_Pressed) {
|
|
|
- gwinPrintf(GW1, "Button 3 pressed\n");
|
|
|
- Capacity_I = dech_Capacity_I;
|
|
|
- Capacity_P = dech_Capacity_P;
|
|
|
- Timer = dechTimer;
|
|
|
+ if (s == 0) {
|
|
|
+ s ++;
|
|
|
+ gwinPrintf(GW1, "Show Charge results\n");
|
|
|
+ gwinPrintf(GW1, "Button 2 pressed\n");
|
|
|
+ Capacity_I = ch_Capacity_I;
|
|
|
+ Capacity_P = ch_Capacity_P;
|
|
|
+ Timer = chTimer;
|
|
|
+ } else {
|
|
|
+ s = 0;
|
|
|
+ gwinPrintf(GW1, "Show Decharge results\n");
|
|
|
+ gwinPrintf(GW1, "Button 3 pressed\n");
|
|
|
+ Capacity_I = dech_Capacity_I;
|
|
|
+ Capacity_P = dech_Capacity_P;
|
|
|
+ Timer = dechTimer;
|
|
|
+ }
|
|
|
|
|
|
chEvtBroadcast(&ina_all_event);
|
|
|
chEvtBroadcast(&time_event);
|
|
@@ -557,7 +614,7 @@ static void btn4_handler(button_state_t state) {
|
|
|
switch(charger_State) {
|
|
|
case Stop:
|
|
|
charger_State = Charge1;
|
|
|
- gwinPrintf(GW1, "Change state to Charge_1\n");
|
|
|
+ //gwinPrintf(GW1, "Change state to Charge_1\n");
|
|
|
gdispFillStringBox(1, 91, 78, 15, "[4] Stop", font1, Yellow, Blue, gJustifyLeft);
|
|
|
break;
|
|
|
|
|
@@ -566,7 +623,7 @@ static void btn4_handler(button_state_t state) {
|
|
|
Current = 0;
|
|
|
Voltage = 0;
|
|
|
Power = 0;
|
|
|
- gwinPrintf(GW1, "Change state to Stop\n");
|
|
|
+ //gwinPrintf(GW1, "Change state to Stop\n");
|
|
|
gdispFillStringBox(1, 91, 78, 15, "[4] Start", font1, Yellow, Blue, gJustifyLeft);
|
|
|
break;
|
|
|
}
|
|
@@ -585,6 +642,44 @@ static void mode_vt_cb(virtual_timer_t *vtp, void * st) {
|
|
|
chSysUnlockFromISR();
|
|
|
}
|
|
|
|
|
|
+static void show_MenuItem(const int item) {
|
|
|
+ char buf[16];
|
|
|
+ int tmp;
|
|
|
+
|
|
|
+ switch (item) {
|
|
|
+ case 1:
|
|
|
+ tmp = (int)charger_Channel + 1;
|
|
|
+ gwinPrintf(GW1, "Channel #%u selected.\n", tmp);
|
|
|
+
|
|
|
+ chsnprintf(buf, 10, "[1] ch.%u", tmp);
|
|
|
+ gdispFillStringBox(1, 1, 78, 15, buf, font1, Yellow, Blue, gJustifyLeft);
|
|
|
+
|
|
|
+ chsnprintf(buf, 12, " - %2uA ", charger_Channels[charger_Channel].max_current/1000);
|
|
|
+ gdispFillStringBox(1, 16, 78, 15, buf, font1, Yellow, Blue, gJustifyLeft);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 2:
|
|
|
+ gwinPrintf(GW1, "Select profile for %s\n", Profile[charger_Profile].Description);
|
|
|
+ chsnprintf(buf, 10, "[2] %s", Profile[charger_Profile].Chemistry);
|
|
|
+ gdispDrawStringBox(1, 31, 78, 15, buf, font1, Yellow, gJustifyLeft);
|
|
|
+ tmp = Profile[charger_Profile].Capacity_mAh / 1000;
|
|
|
+ chsnprintf(buf, 10, "%s/%uAh", Profile[charger_Profile].VoltageNominal, tmp);
|
|
|
+ gdispDrawStringBox(1, 46, 78, 15, " - 12V", font1, Yellow, gJustifyLeft);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 3:
|
|
|
+ /* code */
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 4:
|
|
|
+ /* code */
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Read Voltage & Current, update screen info.
|
|
|
*/
|
|
@@ -595,8 +690,8 @@ static void ina_Process(void) {
|
|
|
static uint32_t sumCurrent=0, sumVoltage=0;
|
|
|
|
|
|
if (INA_Present != 0) {
|
|
|
- current = INA3221_getCurrent(&ina3221, (ina3221_ch_t)current_Channel);
|
|
|
- volt = INA3221_getVoltage(&ina3221, (ina3221_ch_t)current_Channel);
|
|
|
+ current = INA3221_getCurrent(&ina3221, charger_Channel);
|
|
|
+ volt = INA3221_getVoltage(&ina3221, charger_Channel);
|
|
|
|
|
|
if (current < 0) {
|
|
|
current = 1 - current;
|