amiro-os / devices / DiWheelDrive / main.cpp @ ff7ad65b
History | View | Annotate | Download (32.952 KB)
| 1 | 58fe0e0b | Thomas Schöpping | #define BL_CALLBACK_TABLE_ADDR (0x08000000 + 0x01C0) |
|---|---|---|---|
| 2 | #define BL_MAGIC_NUMBER ((uint32_t)0xFF669900u) |
||
| 3 | |||
| 4 | #define SHUTDOWN_NONE 0 |
||
| 5 | #define SHUTDOWN_TRANSPORTATION 1 |
||
| 6 | #define SHUTDOWN_DEEPSLEEP 2 |
||
| 7 | #define SHUTDOWN_HIBERNATE 3 |
||
| 8 | #define SHUTDOWN_RESTART 4 |
||
| 9 | #define SHUTDOWN_HANDLE_REQUEST 5 |
||
| 10 | |||
| 11 | #include <ch.hpp> |
||
| 12 | |||
| 13 | #include <amiro/util/util.h> |
||
| 14 | #include <global.hpp> |
||
| 15 | #include <exti.hpp> |
||
| 16 | |||
| 17 | #include <chprintf.h> |
||
| 18 | #include <shell.h> |
||
| 19 | |||
| 20 | using namespace chibios_rt; |
||
| 21 | |||
| 22 | Global global; |
||
| 23 | |||
| 24 | 10687985 | Thomas Schöpping | struct blVersion_t {
|
| 25 | const uint8_t identifier;
|
||
| 26 | const uint8_t major;
|
||
| 27 | const uint8_t minor;
|
||
| 28 | const uint8_t patch;
|
||
| 29 | } __attribute__((packed)); |
||
| 30 | |||
| 31 | 58fe0e0b | Thomas Schöpping | void systemShutdown() {
|
| 32 | types::kinematic k; |
||
| 33 | uint8_t i; |
||
| 34 | |||
| 35 | // // make sure we assert SYS_PD_N to delay shutdown until we're done.
|
||
| 36 | // boardRequestShutdown();
|
||
| 37 | |||
| 38 | // stop the user thread
|
||
| 39 | global.userThread.requestTerminate(); |
||
| 40 | global.userThread.wait(); |
||
| 41 | |||
| 42 | k.x = 0x00u;
|
||
| 43 | k.w_z = 0x00u;
|
||
| 44 | |||
| 45 | // stop wheels
|
||
| 46 | global.robot.setTargetSpeed(k); |
||
| 47 | global.robot.terminate(); |
||
| 48 | |||
| 49 | for (i = 0x00; i < global.vcnl4020.size(); i++) { |
||
| 50 | global.vcnl4020[i].requestTerminate(); |
||
| 51 | global.vcnl4020[i].wait(); |
||
| 52 | } |
||
| 53 | |||
| 54 | global.ina219.requestTerminate(); |
||
| 55 | global.ina219.wait(); |
||
| 56 | global.hmc5883l.requestTerminate(); |
||
| 57 | global.hmc5883l.wait(); |
||
| 58 | global.l3g4200d.requestTerminate(); |
||
| 59 | global.l3g4200d.wait(); |
||
| 60 | |||
| 61 | global.motorcontrol.requestTerminate(); |
||
| 62 | global.motorcontrol.wait(); |
||
| 63 | global.odometry.requestTerminate(); |
||
| 64 | global.odometry.wait(); |
||
| 65 | |||
| 66 | // stop I²C
|
||
| 67 | for (i = 0; i < global.V_I2C2.size(); ++i) |
||
| 68 | global.V_I2C2[i].stop(); |
||
| 69 | global.HW_I2C2.stop(); |
||
| 70 | |||
| 71 | global.lis331dlh.requestTerminate(); |
||
| 72 | global.lis331dlh.wait(); |
||
| 73 | |||
| 74 | global.lis331dlh.configure(&global.accel_sleep_config); |
||
| 75 | // global.lis331dlh.start(NORMALPRIO +4);
|
||
| 76 | |||
| 77 | // boardWriteIoPower(0);
|
||
| 78 | // boardStandby();
|
||
| 79 | |||
| 80 | return;
|
||
| 81 | } |
||
| 82 | |||
| 83 | |||
| 84 | //void (*shellcmd_t)(BaseSequentialStream *chp, int argc, char *argv[]);
|
||
| 85 | |||
| 86 | void shellRequestShutdown(BaseSequentialStream *chp, int argc, char *argv[]) { |
||
| 87 | |||
| 88 | chprintf(chp, "shellRequestShutdown\n");
|
||
| 89 | |||
| 90 | /* if nor argument was given, print some help text */
|
||
| 91 | if (argc == 0 || strcmp(argv[0], "help") == 0) { |
||
| 92 | chprintf(chp, "\tUSAGE:\n");
|
||
| 93 | chprintf(chp, "> shutdown <type>\n");
|
||
| 94 | chprintf(chp, "\n");
|
||
| 95 | chprintf(chp, "\ttype\n");
|
||
| 96 | chprintf(chp, "The type of shutdown to perform.\n");
|
||
| 97 | chprintf(chp, "Choose one of the following types:\n");
|
||
| 98 | chprintf(chp, " transportation - Ultra low-power mode with all wakeups disabled.\n");
|
||
| 99 | chprintf(chp, " The robot can not be charged.\n");
|
||
| 100 | chprintf(chp, " deepsleep - Ultra low-power mode with several wakeups enabled.\n");
|
||
| 101 | chprintf(chp, " The robot can only be charged via the power plug.\n");
|
||
| 102 | chprintf(chp, " hibernate - Medium low-power mode, but with full charging capabilities.\n");
|
||
| 103 | chprintf(chp, " restart - Performs a system restart.\n");
|
||
| 104 | chprintf(chp, "Alternatively, you can use the shortcuts 't', 'd', 'h', and 'r' respectively.");
|
||
| 105 | chprintf(chp, "\n");
|
||
| 106 | return;
|
||
| 107 | } |
||
| 108 | |||
| 109 | if (strcmp(argv[0],"transportation") == 0 || strcmp(argv[0],"t") == 0) { |
||
| 110 | shutdown_now = SHUTDOWN_TRANSPORTATION; |
||
| 111 | chprintf(chp, "shutdown to transportation mode initialized\n");
|
||
| 112 | } else if (strcmp(argv[0],"deepsleep") == 0 || strcmp(argv[0],"d") == 0) { |
||
| 113 | shutdown_now = SHUTDOWN_DEEPSLEEP; |
||
| 114 | chprintf(chp, "shutdown to deepsleep mode initialized\n");
|
||
| 115 | } else if (strcmp(argv[0],"hibernate") == 0 || strcmp(argv[0],"h") == 0) { |
||
| 116 | shutdown_now = SHUTDOWN_HIBERNATE; |
||
| 117 | chprintf(chp, "shutdown to hibernate mode initialized\n");
|
||
| 118 | } else if (strcmp(argv[0],"restart") == 0 || strcmp(argv[0],"r") == 0) { |
||
| 119 | chprintf(chp, "restart initialized\n");
|
||
| 120 | shutdown_now = SHUTDOWN_RESTART; |
||
| 121 | } else {
|
||
| 122 | chprintf(chp, "ERROR: unknown argument!\n");
|
||
| 123 | shutdown_now = SHUTDOWN_NONE; |
||
| 124 | } |
||
| 125 | |||
| 126 | return;
|
||
| 127 | } |
||
| 128 | |||
| 129 | void shellRequestWakeup(BaseSequentialStream *chp, int argc, char *argv[]) { |
||
| 130 | int i;
|
||
| 131 | chprintf(chp, "shellRequestWakeup\n");
|
||
| 132 | |||
| 133 | for (i = 0x00u; i < argc; i++) |
||
| 134 | chprintf(chp, "%s\n", argv[i]);
|
||
| 135 | |||
| 136 | boardWakeup(); |
||
| 137 | } |
||
| 138 | |||
| 139 | void shellRequestGetMemoryData(BaseSequentialStream *chp, int argc, char *argv[]) { |
||
| 140 | enum Type {HEX, U8, U16, U32, S8, S16, S32};
|
||
| 141 | |||
| 142 | chprintf(chp, "shellRequestReadData\n");
|
||
| 143 | |||
| 144 | if (argc < 2 || strcmp(argv[0],"help") == 0) |
||
| 145 | {
|
||
| 146 | chprintf(chp, "Usage: %s\n","get_memory_data <type> <start> [<count>]"); |
||
| 147 | chprintf(chp, "\n");
|
||
| 148 | chprintf(chp, "\ttype\n");
|
||
| 149 | chprintf(chp, "The data type as which to interpret the data.\n");
|
||
| 150 | chprintf(chp, "Choose one of the following types:\n");
|
||
| 151 | chprintf(chp, " hex - one byte as hexadecimal value\n");
|
||
| 152 | chprintf(chp, " u8 - unsigned integer (8 bit)\n");
|
||
| 153 | chprintf(chp, " u16 - unsigned integer (16 bit)\n");
|
||
| 154 | chprintf(chp, " u32 - unsigned integer (32 bit)\n");
|
||
| 155 | chprintf(chp, " s8 - signed integer (8 bit)\n");
|
||
| 156 | chprintf(chp, " s16 - signed integer (16 bit)\n");
|
||
| 157 | chprintf(chp, " s32 - signed integer (32 bit)\n");
|
||
| 158 | chprintf(chp, "\tstart\n");
|
||
| 159 | chprintf(chp, "The first byte to read from the memory.\n");
|
||
| 160 | chprintf(chp, "\tcount [default = 1]\n");
|
||
| 161 | chprintf(chp, "The number of elements to read.\n");
|
||
| 162 | chprintf(chp, "\n");
|
||
| 163 | chprintf(chp, "\tNOTE\n");
|
||
| 164 | chprintf(chp, "Type conversions of this function might fail.\n");
|
||
| 165 | chprintf(chp, "If so, use type=hex and convert by hand.\n");
|
||
| 166 | chprintf(chp, "\n");
|
||
| 167 | return;
|
||
| 168 | } |
||
| 169 | |||
| 170 | uint8_t type_size = 0;
|
||
| 171 | Type type = HEX; |
||
| 172 | if (strcmp(argv[0],"hex") == 0) { |
||
| 173 | type_size = sizeof(unsigned char); |
||
| 174 | type = HEX; |
||
| 175 | } else if(strcmp(argv[0],"u8") == 0) { |
||
| 176 | type_size = sizeof(uint8_t);
|
||
| 177 | type = U8; |
||
| 178 | } else if(strcmp(argv[0],"u16") == 0) { |
||
| 179 | type_size = sizeof(uint16_t);
|
||
| 180 | type = U16; |
||
| 181 | } else if(strcmp(argv[0],"u32") == 0) { |
||
| 182 | type_size = sizeof(uint32_t);
|
||
| 183 | type = U32; |
||
| 184 | } else if(strcmp(argv[0],"s8") == 0) { |
||
| 185 | type_size = sizeof(int8_t);
|
||
| 186 | type = S8; |
||
| 187 | } else if(strcmp(argv[0],"s16") == 0) { |
||
| 188 | type_size = sizeof(int16_t);
|
||
| 189 | type = S16; |
||
| 190 | } else if(strcmp(argv[0],"s32") == 0) { |
||
| 191 | type_size = sizeof(int32_t);
|
||
| 192 | type = S32; |
||
| 193 | } else {
|
||
| 194 | chprintf(chp, "First argument invalid. Use 'get_memory_data help' for help.\n");
|
||
| 195 | return;
|
||
| 196 | } |
||
| 197 | |||
| 198 | unsigned int start_byte = atoi(argv[1]); |
||
| 199 | |||
| 200 | unsigned int num_elements = 1; |
||
| 201 | if (argc >= 3) |
||
| 202 | num_elements = atoi(argv[2]);
|
||
| 203 | |||
| 204 | const size_t eeprom_size = EEPROM::getsize(&global.at24c01);
|
||
| 205 | uint8_t buffer[eeprom_size]; |
||
| 206 | if (start_byte + (type_size * num_elements) > eeprom_size) {
|
||
| 207 | num_elements = (eeprom_size - start_byte) / type_size; |
||
| 208 | chprintf(chp, "Warning: request exceeds eeprom size -> limiting to %u values.\n", num_elements);
|
||
| 209 | } |
||
| 210 | |||
| 211 | chFileStreamSeek((BaseFileStream*)&global.at24c01, start_byte); |
||
| 212 | |||
| 213 | // Work around, because stm32f1 cannot read a single byte
|
||
| 214 | if (type_size*num_elements < 2) |
||
| 215 | type_size = 2;
|
||
| 216 | |||
| 217 | uint32_t bytes_read = chSequentialStreamRead((BaseFileStream*)&global.at24c01, buffer, type_size*num_elements); |
||
| 218 | |||
| 219 | if (bytes_read != type_size*num_elements)
|
||
| 220 | chprintf(chp, "Warning: %u of %u requested bytes were read.\n", bytes_read, type_size*num_elements);
|
||
| 221 | |||
| 222 | for ( |