1 ////////////////////////////////////////////////////////////////////////////////
3 // Eurobot POWER BOAD (with LPC2129)
7 // This software controls the eurobot powerboard
8 // Author : Jiri Kubias DCE CVUT
11 ////////////////////////////////////////////////////////////////////////////////
13 #include <lpc21xx.h> /* LPC21xx definitions */
16 #include <system_def.h>
17 #include <periph/can.h>
19 #include <can_msg_def.h>
27 struct power power_state;
29 volatile uint32_t timer_msec = 0, timer_usec = 0;
31 void set_irq_handler(uint8_t source, uint8_t irq_vect, void (*handler)())
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;
40 void timer0_irq() __attribute__((interrupt));
43 static unsigned cnt1khz = 0;
48 /* increment timer_usec */
50 /* increment msec @1kHz */
51 if (++cnt1khz == 100) {
60 void init_timer0(uint32_t prescale, uint32_t period)
62 T0TCR = 0x2; /* reset */
65 T0MCR = 0x3; /* match0: reset & irq */
66 T0EMR = 0; /* no ext. match */
67 T0CCR = 0x0; /* no capture */
68 T0TCR = 0x1; /* go! */
71 void can_rx(can_msg_t *msg) {
74 memcpy(&rx_msg, msg, sizeof(can_msg_t));
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;
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;
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;
104 void init_perip(struct power *pwr) // inicializace periferii mikroprocesoru
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 );
110 init_timer0(1, CPU_APB_HZ/100000);
111 set_irq_handler(4 /*timer0*/, TIMER_IRQ_PRIORITY, timer0_irq);
119 static uint32_t led_time = 0;
121 if(timer_msec >= led_time + 500) {
122 led_time = timer_msec;
123 deb_led_change(LEDG);
127 void send_alert(unsigned char alert)
129 msg.id = CAN_PWR_ALERT;
137 void power_lines_check(struct power *pwr)
139 static uint32_t power_time = 0;
140 static unsigned char cnt_33V = 0, cnt_50V = 0, cnt_80V = 0;
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);
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);
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);
168 power_time = timer_msec;
172 void battery_check(struct power *pwr)
174 static uint32_t battery_time = 0;
175 static unsigned char cnt_10V = 0, cnt_11V = 0, cnt_12V = 0;
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) {
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!!
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) {
196 pwr->alert |= CAN_PWR_BATT_LOW;
197 send_alert(pwr->alert);
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) {
205 pwr->alert |= CAN_PWR_BATT_MEAN;
206 send_alert(pwr->alert);
211 battery_time = timer_msec;
217 static uint32_t send_time = 0;
218 static uint32_t can_timeout = 0;
220 if (timer_msec >= send_time + CAN_REPORT_TIME) {
223 msg.id = CAN_PWR_ADC1;
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);
236 can_timeout = timer_msec;
237 while(can_tx_msg(&msg) && (timer_msec <= can_timeout + CAN_TIMEOUT_TIME));
239 msg.id = CAN_PWR_ADC2;
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);
251 can_timeout = timer_msec;
252 while(can_tx_msg(&msg) && (timer_msec <= can_timeout + CAN_TIMEOUT_TIME));
255 send_time = timer_msec;
261 init_perip(&power_state); // sys init MCU
263 //TODO wait one secdond here
268 battery_check(&power_state);
269 power_lines_check(&power_state);