Rev 8 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 2 | mjames | 1 | /* |
| 2 | ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, |
||
| 3 | 2011,2012 Giovanni Di Sirio. |
||
| 4 | |||
| 5 | This file is part of ChibiOS/RT. |
||
| 6 | |||
| 7 | ChibiOS/RT is free software; you can redistribute it and/or modify |
||
| 8 | it under the terms of the GNU General Public License as published by |
||
| 9 | the Free Software Foundation; either version 3 of the License, or |
||
| 10 | (at your option) any later version. |
||
| 11 | |||
| 12 | ChibiOS/RT is distributed in the hope that it will be useful, |
||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
| 15 | GNU General Public License for more details. |
||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License |
||
| 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
| 19 | |||
| 20 | --- |
||
| 21 | |||
| 22 | A special exception to the GPL can be applied should you wish to distribute |
||
| 23 | a combined work that includes ChibiOS/RT, without being obliged to provide |
||
| 24 | the source code for any proprietary components. See the file exception.txt |
||
| 25 | for full details of how and when the exception can be applied. |
||
| 26 | */ |
||
| 27 | |||
| 28 | #include <stdio.h> |
||
| 29 | #include <string.h> |
||
| 9 | mjames | 30 | #include <stdlib.h> |
| 31 | #include <math.h> |
||
| 32 | |||
| 2 | mjames | 33 | |
| 34 | #include "ch.h" |
||
| 35 | #include "hal.h" |
||
| 8 | mjames | 36 | // #include "test.h" |
| 2 | mjames | 37 | #include "shell.h" |
| 38 | #include "evtimer.h" |
||
| 39 | #include "chprintf.h" |
||
| 40 | |||
| 41 | #include "shellCmds.h" |
||
| 42 | |||
| 6 | mjames | 43 | #include "ap_math.h" |
| 44 | #include "spiInterface.h" |
||
| 45 | #include "SSD1306.h" |
||
| 9 | mjames | 46 | #include "Font.h" |
| 2 | mjames | 47 | |
| 8 | mjames | 48 | static MUTEX_DECL(mutexDisplay); |
| 2 | mjames | 49 | |
| 50 | /*===========================================================================*/ |
||
| 51 | /* Command line related. */ |
||
| 52 | /*===========================================================================*/ |
||
| 53 | |||
| 8 | mjames | 54 | #define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(1024) |
| 55 | #define TEST_WA_SIZE THD_WORKING_AREA_SIZE(256) |
||
| 2 | mjames | 56 | |
| 8 | mjames | 57 | #define RPM_ID 0x10d |
| 58 | |||
| 9 | mjames | 59 | // 1 megabit CAN |
| 60 | #define CAN_CONFIG1000 |
||
| 8 | mjames | 61 | |
| 62 | /* |
||
| 63 | * Internal loopback mode, 500KBaud, automatic wakeup, automatic recover |
||
| 64 | * from abort mode. |
||
| 65 | */ |
||
| 66 | |||
| 67 | // CAN_BTR_SJW(n), where n = SJW - 1 |
||
| 68 | // CAN_BTR_BRP(n), where n = prescaler - 1 |
||
| 69 | // CAN_BTR_TS1(n), where n = Seg 1 - 1 |
||
| 70 | // CAN_BTR_TS2(n), where n = Seg 2 - 1 |
||
| 9 | mjames | 71 | #if defined CAN_CONFIG500 |
| 8 | mjames | 72 | static const CANConfig cancfg500 = { |
| 73 | CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP, |
||
| 74 | CAN_BTR_LBKM | CAN_BTR_SJW(0) | CAN_BTR_TS2(2) | |
||
| 75 | CAN_BTR_TS1(3) | CAN_BTR_BRP(8)}; |
||
| 9 | mjames | 76 | #elif defined CAN_CONFIG1000 |
| 8 | mjames | 77 | static const CANConfig cancfg1000 = { |
| 78 | CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP, |
||
| 79 | CAN_BTR_LBKM | CAN_BTR_SJW(0) | CAN_BTR_TS2(2) | |
||
| 80 | CAN_BTR_TS1(4) | CAN_BTR_BRP(3)}; |
||
| 9 | mjames | 81 | #endif |
| 2 | mjames | 82 | static const ShellConfig shell_cfg1 = { |
| 8 | mjames | 83 | (BaseSequentialStream *)&SD1, |
| 84 | shellCommands}; |
||
| 2 | mjames | 85 | //////// |
| 86 | // end of shell stuff |
||
| 87 | |||
| 88 | uint16_t sampIndex; |
||
| 89 | |||
| 8 | mjames | 90 | void setDriveA(uint8_t bit) |
| 91 | { |
||
| 92 | if (bit) |
||
| 93 | { |
||
| 6 | mjames | 94 | palSetPad(GPIOA, GPIOA_A1); |
| 95 | palClearPad(GPIOA, GPIOA_A2); |
||
| 8 | mjames | 96 | } |
| 97 | else |
||
| 98 | { |
||
| 2 | mjames | 99 | palClearPad(GPIOA, GPIOA_A1); |
| 100 | palSetPad(GPIOA, GPIOA_A2); |
||
| 101 | } |
||
| 102 | } |
||
| 103 | |||
| 8 | mjames | 104 | void setDriveB(uint8_t bit) |
| 105 | { |
||
| 106 | if (bit) |
||
| 107 | { |
||
| 6 | mjames | 108 | palSetPad(GPIOA, GPIOA_B1); |
| 109 | palClearPad(GPIOA, GPIOA_B2); |
||
| 8 | mjames | 110 | } |
| 111 | else |
||
| 112 | { |
||
| 2 | mjames | 113 | palClearPad(GPIOA, GPIOA_B1); |
| 114 | palSetPad(GPIOA, GPIOA_B2); |
||
| 115 | } |
||
| 116 | } |
||
| 117 | |||
| 6 | mjames | 118 | // dial settings |
| 119 | volatile int origin = 0; |
||
| 120 | ; |
||
| 121 | volatile int target = 0; |
||
| 2 | mjames | 122 | volatile int count = 0; |
| 123 | |||
| 6 | mjames | 124 | volatile bool pause; |
| 125 | // |
||
| 126 | |||
| 8 | mjames | 127 | void setPause(bool p) |
| 128 | { |
||
| 6 | mjames | 129 | pause = p; |
| 130 | } |
||
| 131 | |||
| 8 | mjames | 132 | static THD_WORKING_AREA(waGaugeThread, 512); |
| 133 | static THD_FUNCTION(gaugeThread, p) { |
||
| 134 | (void)p; |
||
| 6 | mjames | 135 | unsigned const fast = 10; |
| 136 | unsigned const slow = 30; |
||
| 137 | unsigned const range = slow - fast; |
||
| 138 | unsigned del = fast; |
||
| 139 | int step = 1; |
||
| 140 | chRegSetThreadName("Step"); |
||
| 8 | mjames | 141 | while (TRUE) |
| 142 | { |
||
| 2 | mjames | 143 | |
| 6 | mjames | 144 | while (pause) |
| 145 | chThdSleep(1000); |
||
| 146 | |||
| 8 | mjames | 147 | switch (count % 4) |
| 148 | { |
||
| 6 | mjames | 149 | case 0: |
| 150 | setDriveA(1); |
||
| 151 | setDriveB(0); |
||
| 152 | break; |
||
| 153 | case 1: |
||
| 154 | setDriveA(1); |
||
| 155 | setDriveB(1); |
||
| 156 | break; |
||
| 157 | case 2: |
||
| 158 | setDriveA(0); |
||
| 159 | setDriveB(1); |
||
| 160 | break; |
||
| 161 | case 3: |
||
| 162 | setDriveA(0); |
||
| 163 | setDriveB(0); |
||
| 164 | break; |
||
| 2 | mjames | 165 | } |
| 166 | |||
| 167 | // all this calculates minimum distance from |
||
| 168 | // target or origin |
||
| 8 | mjames | 169 | int d1 = abs(count - origin); |
| 170 | int d2 = abs(count - target); |
||
| 6 | mjames | 171 | // finally, minimum distance |
| 9 | mjames | 172 | int dist = d1<d2 ? d1 : d2; |
| 8 | mjames | 173 | |
| 6 | mjames | 174 | del = fast; |
| 175 | if (dist < range) // inside lower bound of distance |
||
| 8 | mjames | 176 | { |
| 6 | mjames | 177 | del = slow - dist; |
| 178 | } |
||
| 179 | chThdSleep(del); |
||
| 2 | mjames | 180 | |
| 8 | mjames | 181 | if (count < target) |
| 182 | { |
||
| 6 | mjames | 183 | step = 1; |
| 184 | } |
||
| 8 | mjames | 185 | if (count > target) |
| 186 | { |
||
| 6 | mjames | 187 | step = -1; |
| 188 | } |
||
| 8 | mjames | 189 | if (count == target) |
| 190 | { |
||
| 6 | mjames | 191 | step = 0; |
| 192 | } |
||
| 193 | count = count + step; |
||
| 194 | } |
||
| 2 | mjames | 195 | } |
| 196 | |||
| 197 | /* |
||
| 198 | * Command Shell Thread |
||
| 199 | */ |
||
| 8 | mjames | 200 | static THD_WORKING_AREA(waShell, 512); |
| 201 | static THD_FUNCTION(shell, p) { |
||
| 202 | (void) p; |
||
| 2 | mjames | 203 | thread_t *shelltp = NULL; |
| 204 | |||
| 205 | chRegSetThreadName("Shell "); |
||
| 6 | mjames | 206 | /* |
| 207 | * in this demo it just performs |
||
| 208 | * a shell respawn upon its termination. |
||
| 209 | */ |
||
| 8 | mjames | 210 | while (true) |
| 211 | { |
||
| 212 | if (!shelltp) |
||
| 213 | { |
||
| 214 | |||
| 215 | shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE, "shell", NORMALPRIO, shellThread, (void *)&shell_cfg1); |
||
| 216 | } |
||
| 217 | else |
||
| 218 | { |
||
| 6 | mjames | 219 | /* If the previous shell exited.*/ |
| 8 | mjames | 220 | if (chThdTerminatedX(shelltp)) |
| 221 | { |
||
| 6 | mjames | 222 | /* Recovers memory of the previous shell.*/ |
| 223 | chThdRelease(shelltp); |
||
| 224 | shelltp = NULL; |
||
| 225 | } |
||
| 226 | } |
||
| 227 | chThdSleepMilliseconds(500); |
||
| 228 | } |
||
| 2 | mjames | 229 | } |
| 230 | |||
| 231 | |||
| 8 | mjames | 232 | static THD_WORKING_AREA(waCanRx, 1024); |
| 233 | static THD_FUNCTION(canRx, p) { |
||
| 234 | (void) p; |
||
| 2 | mjames | 235 | |
| 8 | mjames | 236 | // initialize can bus hardware |
| 237 | event_listener_t el; |
||
| 238 | CANRxFrame rxmsg; |
||
| 2 | mjames | 239 | |
| 8 | mjames | 240 | canStart(&CAND1, &cancfg1000); |
| 6 | mjames | 241 | |
| 8 | mjames | 242 | chRegSetThreadName("CAN receiver"); |
| 243 | chEvtRegister(&CAND1.rxfull_event, &el, 0); |
||
| 244 | while (true) |
||
| 245 | { |
||
| 246 | if (chEvtWaitAnyTimeout(ALL_EVENTS, TIME_MS2I(100)) == 0) |
||
| 247 | continue; |
||
| 248 | while (canReceive(&CAND1, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE) == MSG_OK) |
||
| 249 | { |
||
| 250 | /* Process message.*/ |
||
| 251 | } |
||
| 6 | mjames | 252 | } |
| 8 | mjames | 253 | chEvtUnregister(&CAND1.rxfull_event, &el); |
| 6 | mjames | 254 | } |
| 2 | mjames | 255 | /* |
| 256 | * Application entry point. |
||
| 257 | */ |
||
| 8 | mjames | 258 | int main(void) |
| 259 | { |
||
| 260 | // struct EventListener el0, el1; |
||
| 2 | mjames | 261 | |
| 262 | /* |
||
| 263 | * System initializations. |
||
| 264 | * - HAL initialization, this also initializes the configured device drivers |
||
| 265 | * and performs the board-specific initializations. |
||
| 266 | * - Kernel initialization, the main() function becomes a thread and the |
||
| 267 | * RTOS is active. |
||
| 268 | */ |
||
| 269 | halInit(); |
||
| 270 | chSysInit(); |
||
| 271 | |||
| 6 | mjames | 272 | /* |
| 8 | mjames | 273 | * Initializes serial port. |
| 6 | mjames | 274 | */ |
| 8 | mjames | 275 | sdStart(&SD1, NULL); |
| 2 | mjames | 276 | |
| 6 | mjames | 277 | /* |
| 2 | mjames | 278 | * Shell manager initialization. |
| 279 | */ |
||
| 8 | mjames | 280 | // shellInit(); |
| 6 | mjames | 281 | /* |
| 282 | * initialise approximate maths |
||
| 283 | */ |
||
| 284 | ap_init(); |
||
| 2 | mjames | 285 | |
| 6 | mjames | 286 | chMtxLock(&mutexDisplay); |
| 2 | mjames | 287 | |
| 6 | mjames | 288 | /* start the SPI hardware for display */ |
| 289 | ssd1306spiInit(); |
||
| 290 | |||
| 8 | mjames | 291 | ssd1306_begin(SSD1306_SWITCHCAPVCC, 0); |
| 6 | mjames | 292 | |
| 293 | clearDisplay(); |
||
| 294 | |||
| 295 | display(); |
||
| 296 | |||
| 8 | mjames | 297 | chMtxUnlock(&mutexDisplay); |
| 6 | mjames | 298 | |
| 299 | /* |
||
| 2 | mjames | 300 | * Creates the PLL thread |
| 301 | */ |
||
| 8 | mjames | 302 | chThdCreateStatic(waGaugeThread, sizeof(waGaugeThread), NORMALPRIO, gaugeThread, NULL); |
| 2 | mjames | 303 | |
| 8 | mjames | 304 | chThdCreateStatic(waCanRx, sizeof(waCanRx), NORMALPRIO, canRx, NULL); |
| 2 | mjames | 305 | |
| 8 | mjames | 306 | chThdCreateStatic(waShell, sizeof(waShell), NORMALPRIO, shell, NULL); |
| 2 | mjames | 307 | |
| 8 | mjames | 308 | // reset gauge |
| 6 | mjames | 309 | origin = 540; |
| 8 | mjames | 310 | count = 540; |
| 6 | mjames | 311 | target = 0; |
| 312 | chThdSleepMilliseconds(1000); |
||
| 313 | target = 0; |
||
| 2 | mjames | 314 | |
| 6 | mjames | 315 | int frac = 0; |
| 2 | mjames | 316 | /* start the SPI hardware for display */ |
| 8 | mjames | 317 | while (1) |
| 318 | { |
||
| 2 | mjames | 319 | |
| 8 | mjames | 320 | chThdSleepMilliseconds(100); |
| 321 | unsigned const SCALE = frac * 32 + 16; |
||
| 9 | mjames | 322 | ++frac ; |
| 323 | frac %= 10; |
||
| 2 | mjames | 324 | |
| 8 | mjames | 325 | // read the dial |
| 2 | mjames | 326 | |
| 8 | mjames | 327 | origin = count; |
| 2 | mjames | 328 | |
| 8 | mjames | 329 | target = target + 1; |
| 2 | mjames | 330 | |
| 8 | mjames | 331 | // target = lidar * 630L / 2000L; |
| 2 | mjames | 332 | |
| 8 | mjames | 333 | if (target > 540) |
| 334 | target = 0; |
||
| 2 | mjames | 335 | |
| 8 | mjames | 336 | chMtxLock(&mutexDisplay); |
| 2 | mjames | 337 | |
| 8 | mjames | 338 | font_gotoxy(0, 0); |
| 339 | clearDisplay(); |
||
| 2 | mjames | 340 | |
| 8 | mjames | 341 | // print_scaled_string("cm:",0,16,4,SCALE); |
| 2 | mjames | 342 | |
| 8 | mjames | 343 | print_digits(0, 0, 4, 1, target, SCALE); |
| 2 | mjames | 344 | |
| 8 | mjames | 345 | chMtxUnlock(&mutexDisplay); |
| 6 | mjames | 346 | |
| 8 | mjames | 347 | display(); |
| 6 | mjames | 348 | } |
| 2 | mjames | 349 | } |