Statistics
| Branch: | Tag: | Revision:

amiro-os / devices / PowerManagement / main.cpp @ e404e6c0

History | View | Annotate | Download (42.586 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
struct blVersion_t {
49
  const uint8_t identifier;
50
  const uint8_t major;
51
  const uint8_t minor;
52
  const uint8_t patch;
53
} __attribute__((packed));
54

    
55
void shutdownTimeoutISR(void *arg) {
56

    
57
  (void) arg;
58

    
59
}
60

    
61
void systemStop() {
62

    
63
//  VirtualTimer shutdownTimeout;
64
  uint8_t i;
65

    
66
  // tell all boards that it's time to shut down
67
  global.robot.broadcastShutdown();
68

    
69
  global.userThread.requestTerminate();
70
  global.userThread.wait();
71

    
72
  // kill bluetooth
73
  boardBluetoothSetState(0);
74

    
75
  global.adc1_vsys.requestTerminate();
76
  global.adc1_vsys.wait();
77

    
78
  for (i = 0; i < global.vcnl4020.size(); ++i) {
79
    global.vcnl4020[i].requestTerminate();
80
    global.vcnl4020[i].wait();
81
  }
82

    
83
  for (i = 0; i < global.bq27500.size(); ++i) {
84
    global.bq27500[i].requestTerminate();
85
    global.bq27500[i].wait();
86
  }
87

    
88
  for (i = 0; i < global.ina219.size(); ++i) {
89
    global.ina219[i].requestTerminate();
90
    global.ina219[i].wait();
91
  }
92

    
93
//  boardWriteIoPower(0);
94
  global.mpr121.configure(&global.mpr121_stdby_config);
95
  /* cannot shut down touch, b/c we need it to
96
   * clear any interrupt, so WKUP is not blocked
97
   */
98

    
99
  // stop I²C
100
  for (i = 0; i < global.V_I2C1.size(); ++i)
101
    global.V_I2C1[i].stop();
102
  for (i = 0; i < global.V_I2C2.size(); ++i)
103
    global.V_I2C2[i].stop();
104

    
105
  global.mpr121.requestTerminate();
106
  global.mpr121.wait();
107

    
108
  global.HW_I2C2.stop();
109
  global.HW_I2C1.stop();
110

    
111
  // stop all threads
112
  global.robot.terminate();
113

    
114
//  // 60 sec timeout
115
//  palWritePad(GPIOC, GPIOC_SYS_INT_N, PAL_HIGH);
116
//  chVTSet(&shutdownTimeout, MS2ST(60000), shutdownTimeoutISR, NULL);
117
//  // wait for all boards to release SYS_INT_N
118
//  while (palReadPad(GPIOC, GPIOC_SYS_INT_N)!=PAL_HIGH && chVTIsArmedI(&shutdownTimeout)) {
119
//    BaseThread::sleep(MS2ST(1)); /* must sleep for VT, else it will never fire */
120
//  }
121
//  chVTReset(&shutdownTimeout);
122

    
123
//  chprintf((BaseSequentialStream*) &SD1, "Stop\n");
124
//  boardWriteSystemPower(0);
125
//  boardWriteLed(1);
126
//  boardStop(0x00, 0x00);
127

    
128
//  /*
129
//   * HSI-PLL domain now.
130
//   */
131
//  //chprintf((BaseSequentialStream*) &SD1, "After Stop\n");
132
//  boardWriteLed(1);
133

    
134
//  while (true)
135
//    BaseThread::sleep(MS2ST(250));
136

    
137
  return;
138
}
139

    
140
void systemShutdown() {
141

    
142
  VirtualTimer shutdownTimeout;
143
  uint8_t i;
144

    
145
  // tell all boards that it's time to shut down
146
  global.robot.broadcastShutdown();
147

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

    
151
  // stop the user thread
152
  global.userThread.requestTerminate();
153
  global.userThread.wait();
154

    
155
  // kill bluetooth
156
  boardBluetoothSetState(0);
157

    
158
  // stop all threads
159
  global.robot.terminate();
160

    
161
  global.adc1_vsys.requestTerminate();
162
  global.adc1_vsys.wait();
163

    
164
  for (i = 0; i < global.vcnl4020.size(); ++i) {
165
    global.vcnl4020[i].requestTerminate();
166
    global.vcnl4020[i].wait();
167
  }
168

    
169
  for (i = 0; i < global.bq27500.size(); ++i) {
170
    global.bq27500[i].requestTerminate();
171
    global.bq27500[i].wait();
172
  }
173

    
174
  for (i = 0; i < global.ina219.size(); ++i) {
175
    global.ina219[i].requestTerminate();
176
    global.ina219[i].wait();
177
  }
178

    
179
  // 60 sec timeout
180
  chVTSet(&shutdownTimeout, MS2ST(60000), shutdownTimeoutISR, NULL);
181

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

    
186
  chVTReset(&shutdownTimeout);
187
  boardWriteIoPower(0);
188
  global.mpr121.configure(&global.mpr121_stdby_config);
189
  /* cannot shut down touch, b/c we need it to
190
   * clear any interrupt, so WKUP is not blocked
191
   */
192

    
193
  // stop I²C
194
  for (i = 0; i < global.V_I2C1.size(); ++i)
195
    global.V_I2C1[i].stop();
196
  for (i = 0; i < global.V_I2C2.size(); ++i)
197
    global.V_I2C2[i].stop();
198

    
199
  boardWriteSystemPower(0);
200
  boardStandby();
201

    
202
}
203

    
204

    
205
void boardPeripheryCheck(BaseSequentialStream *chp) {
206

    
207
#ifndef AMIRO_NSELFTEST
208
  chprintf(chp, "\nCHECK: START\n");
209
  msg_t result = 0;
210

    
211
    // Check the proximitysensors
212
  for (uint8_t i = 0; i < global.vcnl4020.size(); i++) {
213
    result = global.vcnl4020[i].getCheck();
214
    if (result == global.vcnl4020[i].CHECK_OK)
215
      chprintf(chp, "VCNL4020: %d OK\n", i);
216
    else
217
      chprintf(chp, "VCNL4020: %d FAIL\n", i);
218
  }
219
  chprintf(chp, "----------------------------------------\n");
220

    
221
  // check the PowerPath controller
222
  chprintf(chp, "\n");
223
  if (global.ltc4412.isPluggedIn())
224
    chprintf(chp, "LTC4412: plugged in\n");
225
  else
226
    chprintf(chp, "LTC4412: not plugged in\n");
227
  chprintf(chp, "----------------------------------------\n");
228

    
229
  // Check the eeprom
230
  result = global.memory.getCheck();
231
  if ( result != global.memory.OK)
232
    chprintf(chp, "Memory Structure: FAIL\n");
233
  else
234
    chprintf(chp, "Memory Structure: OK\n");
235
  chprintf(chp, "----------------------------------------\n");
236

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

    
251
  chprintf(chp, "\n\n");
252
  chprintf(chp, "\tVIO1.8:\n");
253
  uint8_t result_ina219_vio18 = global.ina219[INA_VIO18].selftest();
254
  chprintf(chp, "->\t");
255
  if (result_ina219_vio18 == BaseSensor<>::NOT_IMPLEMENTED)
256
    chprintf(chp, "not implemented");
257
  else if (result_ina219_vio18 != INA219::Driver::ST_OK)
258
    chprintf(chp, "FAIL (error code 0x%02X)", result_ina219_vio18);
259
  else
260
    chprintf(chp, "OK");
261

    
262
  chprintf(chp, "\n\n");
263
  chprintf(chp, "\tVIO3.3:\n");
264
  uint8_t result_ina219_vio33 = global.ina219[INA_VIO33].selftest();
265
  chprintf(chp, "->\t");
266
  if (result_ina219_vio33 == BaseSensor<>::NOT_IMPLEMENTED)
267
    chprintf(chp, "not implemented");
268
  else if (result_ina219_vio33 != INA219::Driver::ST_OK)
269
    chprintf(chp, "FAIL (error code 0x%02X)", result_ina219_vio33);
270
  else
271
    chprintf(chp, "OK");
272

    
273
  chprintf(chp, "\n\n");
274
  chprintf(chp, "\tVIO4.2:\n");
275
  uint8_t result_ina219_vio42 = global.ina219[INA_VIO42].selftest();
276
  chprintf(chp, "->\t");
277
  if (result_ina219_vio42 == BaseSensor<>::NOT_IMPLEMENTED)
278
    chprintf(chp, "not implemented");
279
  else if (result_ina219_vio42 != INA219::Driver::ST_OK)
280
    chprintf(chp, "FAIL (error code 0x%02X)", result_ina219_vio42);
281
  else
282
    chprintf(chp, "OK");
283

    
284
  bus_voltage = global.ina219[INA_VIO42].readBusVoltage();
285
  chprintf(chp, "\n\n");
286
  chprintf(chp, "\tVIO5.0:\n");
287
  uint8_t result_ina219_vio50 = global.ina219[INA_VIO50].selftest();
288
  chprintf(chp, "->\t");
289
  if (result_ina219_vio50 == BaseSensor<>::NOT_IMPLEMENTED)
290
    chprintf(chp, "not implemented");
291
  else if (result_ina219_vio50 != INA219::Driver::ST_OK)
292
    chprintf(chp, "FAIL (error code 0x%02X)", result_ina219_vio50);
293
  else
294
    chprintf(chp, "OK");
295

    
296
  chprintf(chp, "\n\n");
297
  result = result_ina219_vdd | result_ina219_vio18 | result_ina219_vio33 | result_ina219_vio42 | result_ina219_vio50;
298
  if (result == BaseSensor<>::NOT_IMPLEMENTED)
299
    chprintf(chp, "->\tINA219: not implemented\n");
300
  else
301
    chprintf(chp, "->\tINA219: %s\n", (result != INA219::Driver::ST_OK)? "FAIL" : "OK");
302
  chprintf(chp, "----------------------------------------\n");
303

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

    
319
  chprintf(chp, "\n\n");
320
  chprintf(chp, "\tP8:\n");
321
  msg_t result_bq27500_p8 = global.bq27500[BAT_P8].selftest();
322
  chprintf(chp, "->\tP8: ");
323
  if (result == BaseSensor<>::NOT_IMPLEMENTED)
324
    chprintf(chp, "not implemented");
325
  else if (result_bq27500_p8 == BQ27500::Driver::ST_ABORT_NO_BAT)
326
      chprintf(chp, "ABORT (no battery detected)");
327
  else if (result_bq27500_p8 != BQ27500::Driver::ST_OK)
328
    chprintf(chp, "FAIL (error code 0x%02X)", result);
329
  else
330
    chprintf(chp, "OK");
331

    
332
  chprintf(chp, "\n");
333
  result = result_bq27500_p7 | result_bq27500_p8;
334
  if (result == BaseSensor<>::NOT_IMPLEMENTED)
335
    chprintf(chp, "\n->\tBQ27500: not implemented\n");
336
  else
337
    chprintf(chp, "\n->\tBQ27500: %s\n", (result != BQ27500::Driver::ST_OK)? "