forked from Damme/LandLord
-
Notifications
You must be signed in to change notification settings - Fork 0
/
powermgmt.c
134 lines (124 loc) · 4.14 KB
/
powermgmt.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <stdio.h>
#include "powermgmt.h"
#include "timers.h"
#define xDelay100 ((TickType_t)100 / portTICK_PERIOD_MS)
#define IS_CHARGER_CONNECTED() (LPC_GPIO1->FIOPIN & (1<<21))
#define IS_CHARGER_ENABLED() (LPC_GPIO1->FIOPIN & (1<<23))
#define IS_CHARGING() (IS_CHARGER_CONNECTED() && IS_CHARGER_ENABLED())
#define ENABLE_CHARGER() do { LPC_GPIO1->FIOSET = (1<<23); } while(0)
#define DISABLE_CHARGER() do { LPC_GPIO1->FIOCLR = (1<<23); } while(0)
#define BATTERY_MAX_VOLTAGE 287
#define BATTERY_MIN_VOLTAGE 237
xQueueHandle xPowerMgmtMsgQueue;
int32_t lChargeCurrent;
int32_t lBatteryVoltage;
int32_t lBatteryTemperature;
void task_PowerMgmt(void *pvParameters)
{
xPowerMgmtMsgQueue = xQueueCreate(20, sizeof(xPowerMgmtMsg));
lChargeCurrent = INT32_MIN;
lBatteryVoltage = INT32_MIN;
lBatteryTemperature = INT32_MIN;
// P1.21 - Charger connected (input, high active)
// for approx. 2sec after connected to charger (led turns red), it is high
LPC_PINCON->PINMODE3 &= ~(3<<((21-16)*2));
LPC_PINCON->PINMODE3 |= (2<<((21-16)*2)); // no pullup/-down
LPC_PINCON->PINSEL3 &= ~(3<<((21-16)*2)); // plain gpio
LPC_GPIO1->FIODIR &= ~(1<<21); // input
// P1.23 - Enable charger (output, high active)
LPC_PINCON->PINMODE3 &= ~(3<<((23-16)*2));
LPC_PINCON->PINMODE3 |= (2<<((23-16)*2)); // no pullup/-down
LPC_PINCON->PINSEL3 &= ~(3<<((23-16)*2)); // plain gpio
LPC_GPIO1->FIODIR |= (1<<23); // output
DISABLE_CHARGER();
for (;;)
{
xPowerMgmtMsg msg;
if (xQueueReceive(xPowerMgmtMsgQueue, &msg, xDelay100) == pdTRUE)
{
switch (msg.xType)
{
case (MEASUREMENT_BATTERY):
{
/* https://hackaday.io/project/6717-project-landlord/discussion-58892 */
if (msg.measurement.lChargeCurrent != INT32_MIN)
{
lChargeCurrent = msg.measurement.lChargeCurrent;
printf("Charge I: %4umA\r\n", lChargeCurrent);
}
if (msg.measurement.lBatteryVoltage != INT32_MIN)
{
// orig fw: v16_batteryLowV = 237; - 23.7V (fixed point) - 3.386V per cell
// orig fw: v18_batteryFullCharge = 287; - 28.7V (fixed point) - 4.1V per cell
lBatteryVoltage = msg.measurement.lBatteryVoltage;
printf("Battery U: %2u.%01uV\r\n", lBatteryVoltage / 10, lBatteryVoltage % 10);
if ((lBatteryVoltage < BATTERY_MIN_VOLTAGE) && !IS_CHARGER_CONNECTED()) /* below 23.7V - switch off to protect battery! */
{
/* issue shutdown to self */
xPowerMgmtMsg msg;
msg.xType = COMMAND_SHUTDOWN;
msg.shutdown.xDelay = xDelay100;
printf("Requesting shutdown to protect battery!\r\n");
xQueueSend(xPowerMgmtMsgQueue, &msg, (TickType_t)0);
}
else if (lBatteryVoltage > BATTERY_MAX_VOLTAGE) /* over 28.7V - stop charging! */
{
}
}
if (msg.measurement.lBatteryTemperature != INT32_MIN)
{
lBatteryTemperature = msg.measurement.lBatteryTemperature;
printf("Battery T: %3u.%01u%cC\r\n", lBatteryTemperature / 10, lBatteryTemperature % 10, '\xB0');
if (lBatteryTemperature > 400) /* above 40.0°C - switch off to protect battery! */
{
/* issue shutdown to self */
xPowerMgmtMsg msg;
msg.xType = COMMAND_SHUTDOWN;
msg.shutdown.xDelay = xDelay100;
printf("Requesting shutdown to protect battery!\r\n");
xQueueSend(xPowerMgmtMsgQueue, &msg, (TickType_t)0);
}
}
break;
}
case (COMMAND_SHUTDOWN):
{
printf("Shutting down!\r\n");
vTaskDelay(msg.shutdown.xDelay);
LPC_GPIO1->FIOPIN &= ~(PIN(25)); // Shutdown
__disable_irq(); for( ;; );
}
default:
printf("Unknown msg\r\n");
}
}
// on each loop (latest every 100ms), check if connected to charger
if (IS_CHARGER_CONNECTED())
{
if (!IS_CHARGER_ENABLED())
{
if ((lBatteryVoltage > (BATTERY_MIN_VOLTAGE-10)) && (lBatteryVoltage < (BATTERY_MAX_VOLTAGE-10)))
{
printf("Start charging\r\n");
ENABLE_CHARGER();
}
}
else
{
if (lBatteryVoltage >= BATTERY_MAX_VOLTAGE)
{
printf("Stop charging\r\n");
DISABLE_CHARGER();
}
}
}
else
{
if (IS_CHARGER_ENABLED())
{
printf("Charger disconnected\r\n");
DISABLE_CHARGER();
}
}
}
}