Statistics
| Branch: | Tag: | Revision:

amiro-os / devices / PowerManagement / main.cpp @ 58fe0e0b

History | View | Annotate | Download (38.845 KB)

1
#ifndef IN_CCM
2
/*
3
 * @brief Makro to store data in the core coupled memory (ccm).
4
 *        Example:
5
 *        int compute_buffer[128] IN_CCM;
6
 *
7
 * @note The ccm is not connected to any bus system.
8
 */
9
#define IN_CCM  __attribute__((section(".ccm"))) __attribute__((aligned(4)))
10
#endif
11

    
12
#ifndef IN_ETH
13
/*
14
 * @brief Makro to store data in the ethernet memory (eth).
15
 *        Example:
16
 *        int dma_buffer[128] IN_ETH;
17
 *
18
 * @note The eth is a dedicated memory block with its own DMA controller.
19
 */
20
#define IN_ETH  __attribute__((section(".eth"))) __attribute__((aligned(4)))
21
#endif
22

    
23
#define BL_CALLBACK_TABLE_ADDR  (0x08000000 + 0x01C0)
24
#define BL_MAGIC_NUMBER         ((uint32_t)0xFF669900u)
25

    
26
#define SHUTDOWN_NONE             0
27
#define SHUTDOWN_TRANSPORTATION   1
28
#define SHUTDOWN_DEEPSLEEP        2
29
#define SHUTDOWN_HIBERNATE        3
30
#define SHUTDOWN_RESTART          4
31
#define SHUTDOWN_HANDLE_REQUEST   5
32

    
33
#include <ch.hpp>
34
#include <shell.h>
35
#include <chprintf.h>
36
#include <wakeup.h>
37
#include <cstdlib>
38
#include <cstring>
39
#include <amiro/util/util.h>
40
#include <global.hpp>
41
#include <exti.hpp>
42

    
43
using namespace amiro;
44
using namespace constants::PowerManagement;
45

    
46
Global global;
47

    
48
void shutdownTimeoutISR(void *arg) {
49

    
50
  (void) arg;
51

    
52
}
53

    
54
void systemStop() {
55

    
56
//  VirtualTimer shutdownTimeout;
57
  uint8_t i;
58

    
59
  // tell all boards that it's time to shut down
60
  global.robot.broadcastShutdown();
61

    
62
  global.userThread.requestTerminate();
63
  global.userThread.wait();
64

    
65
  // kill bluetooth
66
  boardBluetoothSetState(0);
67

    
68
  global.adc1_vsys.requestTerminate();
69
  global.adc1_vsys.wait();
70

    
71
  for (i = 0; i < global.vcnl4020.size(); ++i) {
72
    global.vcnl4020[i].requestTerminate();
73
    global.vcnl4020[i].wait();
74
  }
75

    
76
  for (i = 0; i < global.bq27500.size(); ++i) {
77
    global.bq27500[i].requestTerminate();
78
    global.bq27500[i].wait();
79
  }
80

    
81
  for (i = 0; i < global.ina219.size(); ++i) {
82
    global.ina219[i].requestTerminate();
83
    global.ina219[i].wait();
84
  }
85

    
86
//  boardWriteIoPower(0);
87
  global.mpr121.configure(&global.mpr121_stdby_config);
88
  /* cannot shut down touch, b/c we need it to
89
   * clear any interrupt, so WKUP is not blocked
90
   */
91

    
92
  // stop I²C
93
  for (i = 0; i < global.V_I2C1.size(); ++i)
94
    global.V_I2C1[i].stop();
95
  for (i = 0; i < global.V_I2C2.size(); ++i)
96
    global.V_I2C2[i].stop();
97

    
98
  global.mpr121.requestTerminate();
99
  global.mpr121.wait();
100

    
101
  global.HW_I2C2.stop();
102
  global.HW_I2C1.stop();
103

    
104
  // stop all threads
105
  global.robot.terminate();
106

    
107
//  // 60 sec timeout
108
//  palWritePad(GPIOC, GPIOC_SYS_INT_N, PAL_HIGH);
109
//  chVTSet(&shutdownTimeout, MS2ST(60000), shutdownTimeoutISR, NULL);
110
//  // wait for all boards to release SYS_INT_N
111
//  while (palReadPad(GPIOC, GPIOC_SYS_INT_N)!=PAL_HIGH && chVTIsArmedI(&shutdownTimeout)) {
112
//    BaseThread::sleep(MS2ST(1)); /* must sleep for VT, else it will never fire */
113
//  }
114
//  chVTReset(&shutdownTimeout);
115

    
116
//  chprintf((BaseSequentialStream*) &SD1, "Stop\n");
117
//  boardWriteSystemPower(0);
118
//  boardWriteLed(1);
119
//  boardStop(0x00, 0x00);
120

    
121
//  /*
122
//   * HSI-PLL domain now.
123
//   */
124
//  //chprintf((BaseSequentialStream*) &SD1, "After Stop\n");
125
//  boardWriteLed(1);
126

    
127
//  while (true)
128
//    BaseThread::sleep(MS2ST(250));
129

    
130
  return;
131
}
132

    
133
void systemShutdown() {
134

    
135
  VirtualTimer shutdownTimeout;
136
  uint8_t i;
137

    
138
  // tell all boards that it's time to shut down
139
  global.robot.broadcastShutdown();
140

    
141
  // wait a little to make sure all boards got the message and had time to pull their SYS_PD_N pins down
142
  BaseThread::sleep(MS2ST(500));
143

    
144
  // stop the user thread
145
  global.userThread.requestTerminate();
146
  global.userThread.wait();
147

    
148
  // kill bluetooth
149
  boardBluetoothSetState(0);
150

    
151
  // stop all threads
152
  global.robot.terminate();
153

    
154
  global.adc1_vsys.requestTerminate();
155
  global.adc1_vsys.wait();
156

    
157
  for (i = 0; i < global.vcnl4020.size(); ++i) {
158
    global.vcnl4020[i].requestTerminate();
159
    global.vcnl4020[i].wait();
160
  }
161

    
162
  for (i = 0; i < global.bq27500.size(); ++i) {
163
    global.bq27500[i].requestTerminate();
164
    global.bq27500[i].wait();
165
  }
166

    
167
  for (i = 0; i < global.ina219.size(); ++i) {
168
    global.ina219[i].requestTerminate();
169
    global.ina219[i].wait();
170
  }
171

    
172
  // 60 sec timeout
173
  chVTSet(&shutdownTimeout, MS2ST(60000), shutdownTimeoutISR, NULL);
174

    
175
  // wait for all boards to release SYS_PD_N
176
  while (!palReadPad(GPIOC, GPIOC_SYS_PD_N) && chVTIsArmedI(&shutdownTimeout))
177
    BaseThread::sleep(MS2ST(1)); /* must sleep for VT, else it will never fire */
178

    
179
  chVTReset(&shutdownTimeout);
180
  boardWriteIoPower(0);
181
  global.mpr121.configure(&global.mpr121_stdby_config);
182
  /* cannot shut down touch, b/c we need it to
183
   * clear any interrupt, so WKUP is not blocked
184
   */
185

    
186
  // stop I²C
187
  for (i = 0; i < global.V_I2C1.size(); ++i)
188
    global.V_I2C1[i].stop();
189
  for (i = 0; i < global.V_I2C2.size(); ++i)
190
    global.V_I2C2[i].stop();
191

    
192
  boardWriteSystemPower(0);
193
  boardStandby();
194

    
195
}
196

    
197

    
198
void boardPeripheryCheck(BaseSequentialStream *chp) {
199

    
200
#ifndef AMIRO_NSELFTEST
201
  chprintf(chp, "\nCHECK: START\n");
202
  msg_t result = 0;
203

    
204
    // Check the proximitysensors
205
  for (uint8_t i = 0; i < global.vcnl4020.size(); i++) {
206
    result = global.vcnl4020[i].getCheck();
207
    if (result == global.vcnl4020[i].CHECK_OK)
208
      chprintf(chp, "VCNL4020: %d OK\n", i);
209
    else
210
      chprintf(chp, "VCNL4020: %d FAIL\n", i);
211
  }
212
  chprintf(chp, "----------------------------------------\n");
213

    
214
  // check the PowerPath controller
215
  chprintf(chp, "\n");
216
  if (global.ltc4412.isPluggedIn())
217
    chprintf(chp, "LTC4412: plugged in\n");
218
  else
219
    chprintf(chp, "LTC4412: not plugged in\n");
220
  chprintf(chp, "----------------------------------------\n");
221

    
222
  // Check the eeprom
223
  result = global.memory.getCheck();
224
  if ( result != global.memory.OK)
225
    chprintf(chp, "Memory Structure: FAIL\n");
226
  else
227
    chprintf(chp, "Memory Structure: OK\n");
228
  chprintf(chp, "----------------------------------------\n");
229

    
230
  // Check the power monitors
231
  INA219::BusVoltage bus_voltage;
232
  chprintf(chp, "\n");
233
  chprintf(chp, "INA219:\n");
234
  chprintf(chp, "\tVDD (3.3V):\n");
235
  uint8_t result_ina219_vdd = global.ina219[INA_VDD].selftest();
236
  chprintf(chp, "->\t");
237
  if (result_ina219_vdd == BaseSensor<>::NOT_IMPLEMENTED)
238
    chprintf(chp, "not implemented");
239
  else if (result_ina219_vdd != INA219::Driver::ST_OK)
240
    chprintf(chp, "FAIL (error code 0x%02X)", result_ina219_vdd);
241
  else
242
    chprintf(chp, "OK");
243

    
244
  chprintf(chp, "\n\n");
245
  chprintf(chp, "\tVIO1.8:\n");
246
  uint8_t result_ina219_vio18 = global.ina219[INA_VIO18].selftest();
247
  chprintf(chp, "->\t");
248
  if (result_ina219_vio18 == BaseSensor<>::NOT_IMPLEMENTED)
249
    chprintf(chp, "not implemented");
250
  else if (result_ina219_vio18 != INA219::Driver::ST_OK)
251
    chprintf(chp, "FAIL (error code 0x%02X)", result_ina219_vio18);
252
  else
253
    chprintf(chp, "OK");
254

    
255
  chprintf(chp, "\n\n");
256
  chprintf(chp, "\tVIO3.3:\n");
257
  uint8_t result_ina219_vio33 = global.ina219[INA_VIO33].selftest();
258
  chprintf(chp, "->\t");
259
  if (result_ina219_vio33 == BaseSensor<>::NOT_IMPLEMENTED)
260
    chprintf(chp, "not implemented");
261
  else if (result_ina219_vio33 != INA219::Driver::ST_OK)
262
    chprintf(chp, "FAIL (error code 0x%02X)", result_ina219_vio33);
263
  else
264
    chprintf(chp, "OK");
265

    
266
  chprintf(chp, "\n\n");
267
  chprintf(chp, "\tVIO4.2:\n");
268
  uint8_t result_ina219_vio42 = global.ina219[INA_VIO42].selftest();
269
  chprintf(chp, "->\t");
270
  if (result_ina219_vio42 == BaseSensor<>::NOT_IMPLEMENTED)
271
    chprintf(chp, "not implemented");
272
  else if (result_ina219_vio42 != INA219::Driver::ST_OK)
273
    chprintf(chp, "FAIL (error code 0x%02X)", result_ina219_vio42);
274
  else
275
    chprintf(chp, "OK");
276

    
277
  bus_voltage = global.ina219[INA_VIO42].readBusVoltage();
278
  chprintf(chp, "\n\n");
279
  chprintf(chp, "\tVIO5.0:\n");
280
  uint8_t result_ina219_vio50 = global.ina219[INA_VIO50].selftest();
281
  chprintf(chp, "->\t");
282
  if (result_ina219_vio50 == BaseSensor<>::NOT_IMPLEMENTED)
283
    chprintf(chp, "not implemented");
284
  else if (result_ina219_vio50 != INA219::Driver::ST_OK)
285
    chprintf(chp, "FAIL (error code 0x%02X)", result_ina219_vio50);
286
  else
287
    chprintf(chp, "OK");
288

    
289
  chprintf(chp, "\n\n");
290
  result = result_ina219_vdd | result_ina219_vio18 | result_ina219_vio33 | result_ina219_vio42 | result_ina219_vio50;
291
  if (result == BaseSensor<>::NOT_IMPLEMENTED)
292
    chprintf(chp, "->\tINA219: not implemented\n");
293
  else
294
    chprintf(chp, "->\tINA219: %s\n", (result != INA219::Driver::ST_OK)? "FAIL" : "OK");
295
  chprintf(chp, "----------------------------------------\n");
296

    
297
  // check the fuel gauges
298
  chprintf(chp, "\n");
299
  chprintf(chp, "BQ27500:\n");
300
  chprintf(chp, "\tP7:\n");
301
  msg_t result_bq27500_p7 = global.bq27500[BAT_P7].selftest();
302
  chprintf(chp, "->\tP7: ");
303
  if (result == BaseSensor<>::NOT_IMPLEMENTED)
304
    chprintf(chp, "not implemented");
305
  else if (result_bq27500_p7 == BQ27500::Driver::ST_ABORT_NO_BAT)
306
    chprintf(chp, "ABORT (no battery detected)");
307
  else if (result_bq27500_p7 != BQ27500::Driver::ST_OK)
308
    chprintf(chp, "FAIL (error code 0x%02X)", result);
309
  else
310
    chprintf(chp, "OK");
311

    
312
  chprintf(chp, "\n\n");
313
  chprintf(chp, "\tP8:\n");
314
  msg_t result_bq27500_p8 = global.bq27500[BAT_P8].selftest();
315
  chprintf(chp, "->\tP8: ");
316
  if (result == BaseSensor<>::NOT_IMPLEMENTED)
317
    chprintf(chp, "not implemented");
318
  else if (result_bq27500_p8 == BQ27500::Driver::ST_ABORT_NO_BAT)
319
      chprintf(chp, "ABORT (no battery detected)");
320
  else if (result_bq27500_p8 != BQ27500::Driver::ST_OK)
321
    chprintf(chp, "FAIL (error code 0x%02X)", result);
322
  else
323
    chprintf(chp, "OK");
324

    
325
  chprintf(chp, "\n");
326
  result = result_bq27500_p7 | result_bq27500_p8;
327
  if (result == BaseSensor<>::NOT_IMPLEMENTED)
328
    chprintf(chp, "\n->\tBQ27500: not implemented\n");
329
  else
330
    chprintf(chp, "\n->\tBQ27500: %s\n", (result != BQ27500::Driver::ST_OK)? "FAIL" : "OK");
331
  chprintf(chp, "----------------------------------------\n");
332

    
333
  // check the chargers
334
  chprintf(chp, "\n");
335