]> rtime.felk.cvut.cz Git - eurobot/public.git/blob - src/eb_pwr/main.c
eb_pwr: New version of power management.
[eurobot/public.git] / src / eb_pwr / main.c
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 //                 Eurobot POWER BOAD  (with LPC2129)
4 //
5 // Description
6 // -----------
7 // This software controls the eurobot powerboard
8 // Author : Jiri Kubias DCE CVUT
9 //
10 //
11 ////////////////////////////////////////////////////////////////////////////////
12
13 #include <lpc21xx.h>                            /* LPC21xx definitions */
14 #include <string.h>
15 #include <deb_led.h>
16 #include <system_def.h>
17 #include <periph/can.h>
18 #include <can_ids.h>
19 #include <can_msg_def.h>
20
21 #include "pwrstep.h"
22 #include "uart.h"
23 #include "def.h"
24
25 can_msg_t msg;
26
27 struct power power_state;
28
29 volatile uint32_t timer_msec = 0, timer_usec = 0;
30
31 void set_irq_handler(uint8_t source, uint8_t irq_vect, void (*handler)())
32 {
33         /* set interrupt vector */
34         ((uint32_t*)&VICVectAddr0)[irq_vect] = (uint32_t)handler;
35         ((uint32_t*)&VICVectCntl0)[irq_vect] = 0x20 | source;
36         /* enable interrupt */
37         VICIntEnable = 1<<source;
38 }
39
40 void timer0_irq() __attribute__((interrupt));
41 void timer0_irq()
42 {
43         static unsigned cnt1khz = 0;
44
45         /* reset timer irq */
46         T0IR = -1;
47
48         /* increment timer_usec */
49         timer_usec += 10;
50         /* increment msec @1kHz */
51         if (++cnt1khz == 100) {
52                 cnt1khz = 0;
53                 ++timer_msec;
54         }
55
56         /* int acknowledge */
57         VICVectAddr = 0;
58 }
59
60 void init_timer0(uint32_t prescale, uint32_t period)
61 {
62         T0TCR = 0x2; /* reset */
63         T0PR = prescale - 1;
64         T0MR0 = period;
65         T0MCR = 0x3; /* match0: reset & irq */
66         T0EMR = 0; /* no ext. match */
67         T0CCR = 0x0; /* no capture */
68         T0TCR = 0x1; /* go! */
69 }
70
71 void can_rx(can_msg_t *msg) {
72         can_msg_t rx_msg;
73
74         memcpy(&rx_msg, msg, sizeof(can_msg_t));
75
76         if (rx_msg.id == CAN_PWR) {
77                 /* set 3.3V power line */
78                 if ((rx_msg.data[0] & (1<<0)) && !(rx_msg.data[0] & (1<<3))) {
79                         pwr_33(PWR_ON, &power_state);
80                         power_state.can_33v_req = PWR_ON;
81                 } else if (rx_msg.data[0] & (1<<3)) {
82                         pwr_33(PWR_OFF, &power_state);
83                         power_state.can_33v_req = PWR_OFF;
84                 }
85                 /* set 5.0V power line */
86                 if ((rx_msg.data[0] & (1<<1)) && !(rx_msg.data[0] & (1<<4))) {
87                         pwr_50(PWR_ON, &power_state);
88                         power_state.can_50v_req = PWR_ON;
89                 } else if (rx_msg.data[0] & (1<<4)) {
90                         pwr_50(PWR_OFF, &power_state);
91                         power_state.can_50v_req = PWR_OFF;
92                 }
93                 /* set 8.0V power line */
94                 if ((rx_msg.data[0] & (1<<2)) && !(rx_msg.data[0] & (1<<5))) {
95                         pwr_80(PWR_ON, &power_state);
96                         power_state.can_80v_req = PWR_ON;
97                 } else if(rx_msg.data[0] & (1<<5)) {
98                         pwr_80(PWR_OFF, &power_state);
99                         power_state.can_80v_req = PWR_OFF;
100                 }
101         }
102 }
103
104 void init_perip(struct power *pwr)      // inicializace periferii mikroprocesoru
105 {
106         can_init_baudrate(CAN_SPEED, CAN_ISR, can_rx);
107         init_uart0((int)9600 ,UART_BITS_8, UART_STOP_BIT_1, UART_PARIT_OFF, 0 );
108         init_adc(ADC_ISR);
109         init_pwr(pwr);
110         init_timer0(1, CPU_APB_HZ/100000);
111         set_irq_handler(4 /*timer0*/, TIMER_IRQ_PRIORITY, timer0_irq);
112
113         pwr_80(PWR_ON, pwr);
114         pwr_50(PWR_ON, pwr);
115 }
116
117 void blink_led()
118 {
119         static uint32_t led_time = 0;
120
121         if(timer_msec >= led_time + 500) {
122                 led_time = timer_msec;
123                 deb_led_change(LEDG);
124         }
125 }
126
127 void send_alert(unsigned char alert)
128 {
129         msg.id = CAN_PWR_ALERT;
130         msg.flags = 0;
131         msg.dlc = 1;
132         msg.data[0] = alert;
133
134         can_tx_msg(&msg);
135 }
136
137 void power_lines_check(struct power *pwr)
138 {
139         static uint32_t power_time = 0;
140         static unsigned char cnt_33V = 0, cnt_50V = 0, cnt_80V = 0;
141
142         //TODO dodelat kontrolu napajecich vetvi tak aby se merilo cca 10x po sobe a pak vyhodnotila situace
143         if (timer_msec >= power_time + CAN_ALERT_TIME) {
144                 if ((V80_CH < V80_MIN || V80_CH > V80_MAX) && (pwr->pwr_80v_state == PWR_ON)) {
145                         if (++cnt_80V > 20) {
146                                 pwr->alert |= CAN_PWR_ALERT_80;
147                                 send_alert(pwr->alert);
148                                 //pwr_80(PWR_OFF, pwr);
149                         }
150                 }
151
152                 if ((V50_CH < V50_MIN || V50_CH > V50_MAX) && (pwr->pwr_50v_state == PWR_ON)) {
153                         if (++cnt_50V > 20) {
154                                 pwr->alert |= CAN_PWR_ALERT_50;
155                                 send_alert(pwr->alert);
156                                 pwr_50(PWR_OFF, pwr);
157                         }
158                 }
159
160                 if ((V33_CH < V33_MIN || V33_CH > V33_MAX) && (pwr->pwr_33v_state == PWR_ON)) {
161                         if (++cnt_33V > 10) {
162                                 pwr->alert |= CAN_PWR_ALERT_33;
163                                 send_alert(pwr->alert);
164                                 pwr_33(PWR_OFF, pwr);
165                         }
166                 }
167
168                 power_time = timer_msec;
169         }
170 }
171
172 void battery_check(struct power *pwr)
173 {
174         static uint32_t battery_time = 0;
175         static unsigned char cnt_10V = 0, cnt_11V = 0, cnt_12V = 0;
176
177         //TODO upravit mereni baterie, po zapnuti napajeni cekat cca 5s a merit stav, pokud OK, zapnout dasli vetve ap.
178         if (timer_msec >= battery_time + 200) {
179                         /* check battery empty state - Ubat < 10.5 V */
180                         /* red LED signalization */
181                         if (BATTERY_CH < BAT_STAT_CRITICAL) {
182                                 if (++cnt_10V > 20) {
183                                         deb_led_on(LEDR);
184                                         pwr->alert |= CAN_PWR_BATT_CRITICAL;
185                                         send_alert(pwr->alert);
186                                         pwr_50(PWR_OFF, pwr);
187                                         pwr_33(PWR_OFF, pwr);
188                                         /// do not switch off 8V pwr line - this will cause power-down of this board!!
189                                 }
190                         }
191                         /* check battery low state - Ubat < 11V */
192                         /* blue LED signalization*/
193                         else if (BATTERY_CH < BAT_STAT_LOW) {
194                                 if (++cnt_11V > BAT_CNT) {
195                                         deb_led_on(LEDY);
196                                         pwr->alert |= CAN_PWR_BATT_LOW;
197                                         send_alert(pwr->alert);
198                                 }
199                         }
200                         /* check battery alert state - Ubat < 12V */
201                         /* yellow LED signalization*/
202                         else if (BATTERY_CH < BAT_STAT_MEAN) {
203                                 if (++cnt_12V > BAT_CNT) {
204                                         deb_led_on(LEDY);
205                                         pwr->alert |= CAN_PWR_BATT_MEAN;
206                                         send_alert(pwr->alert);
207                                 }
208                         } else {
209                                 /* batery OK */
210                         }
211                 battery_time = timer_msec;
212         }
213 }
214
215 void send_voltage()
216 {
217         static uint32_t send_time = 0;
218         static uint32_t can_timeout = 0;
219
220         if (timer_msec >= send_time + CAN_REPORT_TIME) {
221                 deb_led_on(LEDB);
222
223                 msg.id = CAN_PWR_ADC1;
224                 msg.flags = 0;
225                 msg.dlc = 8;
226                 msg.data[0] = (((adc_val[0]) >> 24) & 0xFF);
227                 msg.data[1] = (((adc_val[0]) >> 16) & 0xFF);
228                 msg.data[2] = (((adc_val[0]) >> 8) & 0xFF);
229                 msg.data[3] = (((adc_val[0]) >> 0) & 0xFF);
230                 msg.data[4] = (((adc_val[1]) >> 24) & 0xFF);
231                 msg.data[5] = (((adc_val[1]) >> 16) & 0xFF);
232                 msg.data[6] = (((adc_val[1]) >> 8) & 0xFF);
233                 msg.data[7] = (((adc_val[1]) >> 0) & 0xFF);
234
235
236                 can_timeout = timer_msec;
237                 while(can_tx_msg(&msg) && (timer_msec <= can_timeout + CAN_TIMEOUT_TIME));
238
239                 msg.id = CAN_PWR_ADC2;
240                 msg.flags = 0;
241                 msg.dlc = 8;
242                 msg.data[0] = (((adc_val[2]) >> 24) & 0xFF);
243                 msg.data[1] = (((adc_val[2]) >> 16) & 0xFF);
244                 msg.data[2] = (((adc_val[2]) >> 8) & 0xFF);
245                 msg.data[3] = (((adc_val[2]) >> 0) & 0xFF);
246                 msg.data[4] = (((adc_val[3]) >> 24) & 0xFF);
247                 msg.data[5] = (((adc_val[3]) >> 16) & 0xFF);
248                 msg.data[6] = (((adc_val[3]) >> 8) & 0xFF);
249                 msg.data[7] = (((adc_val[3]) >> 0) & 0xFF);
250
251                 can_timeout = timer_msec;
252                 while(can_tx_msg(&msg) && (timer_msec <= can_timeout + CAN_TIMEOUT_TIME));
253
254                 deb_led_off(LEDB);
255                 send_time = timer_msec;
256         }
257 }
258
259 int main (void)
260 {
261         init_perip(&power_state);       // sys init MCU
262
263         //TODO wait one secdond here
264
265         while (1) {
266                 blink_led();
267                 send_voltage();
268                 battery_check(&power_state);
269                 power_lines_check(&power_state);
270         }
271 }