-
Notifications
You must be signed in to change notification settings - Fork 25
/
power.c
144 lines (137 loc) · 4.21 KB
/
power.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
135
136
137
138
139
140
141
142
143
144
#include "power.h"
#include "hw_conf.h"
#include "analog.h"
#include "current_monitor.h"
#include "config.h"
#include "charger.h"
#include "rtcc.h"
#include "faults.h"
static volatile bool discharge_enabled = false;
static volatile bool precharged = false;
static volatile systime_t prechargeStartTime;
static volatile PowerOnEvent power_on_event;
static volatile bool power_button_released = false;
static volatile bool shutdownStarted = false;
static volatile bool shutdown = false;
static volatile systime_t shutdownStartTime;
static volatile Config *config;
void power_init(void)
{
config = config_get_configuration();
palClearPad(DSG_SW_GPIO, DSG_SW_PIN);
palClearPad(PCHG_SW_GPIO, PCHG_SW_PIN);
if (!palReadPad(PWR_BTN_GPIO, PWR_BTN_PIN))
power_on_event = EVENT_SWITCH;
else if (analog_charger_input_voltage() > 6.0)
power_on_event = EVENT_CHARGER;
#if defined(BATTMAN_4_1) || defined(BATTMAN_4_2)
else if (!palReadPad(RTCC_INT_GPIO, RTCC_INT_PIN))
power_on_event = EVENT_RTCC;
#endif
#if defined(BATTMAN_4_2)
else if (palReadPad(USB_DETECT_GPIO, USB_DETECT_PIN))
{
power_on_event = EVENT_USB;
}
#endif
if (power_on_event == EVENT_SWITCH)
{
chThdSleepMilliseconds(config->turnOnDelay);
discharge_enabled = true;
}
if (power_on_event != EVENT_USB)
palSetPad(PWR_SW_GPIO, PWR_SW_PIN);
}
void power_update(void)
{
if (!shutdown && power_on_event != EVENT_USB)
palSetPad(PWR_SW_GPIO, PWR_SW_PIN);
if (discharge_enabled && faults_get_faults() == FAULT_NONE)
{
if (!precharged)
{
prechargeStartTime = chVTGetSystemTime();
precharged = true;
}
if (precharged)
{
if (ST2MS(chVTTimeElapsedSinceX(prechargeStartTime)) > 8)
{
if (analog_discharge_voltage() < 0.5) // Turned on into short
{
palClearPad(DSG_SW_GPIO, DSG_SW_PIN);
palClearPad(PCHG_SW_GPIO, PCHG_SW_PIN);
faults_set_fault(FAULT_TURN_ON_SHORT);
return;
}
}
if (analog_discharge_voltage() >= current_monitor_get_bus_voltage() - 5.0 || ST2MS(chVTTimeElapsedSinceX(prechargeStartTime)) > config->prechargeTimeout)
{
palSetPad(DSG_SW_GPIO, DSG_SW_PIN);
palClearPad(PCHG_SW_GPIO, PCHG_SW_PIN);
}
else
{
palSetPad(PCHG_SW_GPIO, PCHG_SW_PIN);
palClearPad(DSG_SW_GPIO, DSG_SW_PIN);
}
}
else
{
palClearPad(DSG_SW_GPIO, DSG_SW_PIN);
palClearPad(PCHG_SW_GPIO, PCHG_SW_PIN);
}
}
else
{
palClearPad(DSG_SW_GPIO, DSG_SW_PIN);
palClearPad(PCHG_SW_GPIO, PCHG_SW_PIN);
precharged = false;
}
if (palReadPad(PWR_BTN_GPIO, PWR_BTN_PIN))
power_button_released = true;
if (shutdown || (config->chargerDisconnectShutdown && power_on_event == EVENT_CHARGER && analog_charger_input_voltage() < 6.0))
{
shutdown = true;
rtcc_enable_alarm();
palClearPad(DSG_SW_GPIO, DSG_SW_PIN);
palClearPad(PWR_SW_GPIO, PWR_SW_PIN);
}
else if (((!palReadPad(PWR_BTN_GPIO, PWR_BTN_PIN) && power_button_released) && analog_charger_input_voltage() < 6.0 && !palReadPad(USB_DETECT_GPIO, USB_DETECT_PIN)) || power_on_event == EVENT_RTCC)
{
if (!shutdownStarted)
{
shutdownStartTime = chVTGetSystemTime();
shutdownStarted = true;
}
if (ST2MS(chVTTimeElapsedSinceX(shutdownStartTime)) > config->shutdownDelay)
{
rtcc_enable_alarm();
palClearPad(DSG_SW_GPIO, DSG_SW_PIN);
palClearPad(PWR_SW_GPIO, PWR_SW_PIN);
shutdown = true;
}
}
else
{
shutdown = false;
shutdownStarted = false;
}
}
void power_enable_discharge(void)
{
discharge_enabled = true;
}
void power_disable_discharge(void)
{
discharge_enabled = false;
palClearPad(DSG_SW_GPIO, DSG_SW_PIN);
}
bool power_is_shutdown(void)
{
return shutdown;
}
PowerOnEvent power_get_power_on_event(void)
{
return power_on_event;
}