An example project for the Heltec Turtle LoRa board (STM32L4 and SX1276 chips). The projects is only supported for the Nucleo-L432KC board platform in the mbed online and offline compiler environment. Visit www.radioshuttle.de (choose Turtle board) for instructions. Note that most source files and libraries are open source, however some files especially the RadioShuttle core protocol is copyrighted work. Check header for details.

Dependencies:   mbed BufferedSerial SX1276GenericLib OLED_SSD1306 HELIOS_Si7021 NVProperty RadioShuttle-STM32L4 USBDeviceHT

Committer:
Helmut Tschemernjak
Date:
Wed Feb 13 14:50:50 2019 +0100
Revision:
38:1f3792d6f9ec
Parent:
37:77fa81e4ad79
Child:
39:ee20fe5c9253
Updated MemoryAvailable

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Helmut64 0:3b6c2ce051a6 1 /*
Helmut Tschemernjak 1:56fdc660a26a 2 * Copyright (c) 2019 Helmut Tschemernjak
Helmut64 0:3b6c2ce051a6 3 * 30826 Garbsen (Hannover) Germany
Helmut64 0:3b6c2ce051a6 4 */
Helmut Tschemernjak 1:56fdc660a26a 5 #include "main.h"
Helmut Tschemernjak 37:77fa81e4ad79 6 #include "GenericPingPong.h"
Helmut Tschemernjak 37:77fa81e4ad79 7 #ifdef TOOLCHAIN_GCC
Helmut Tschemernjak 37:77fa81e4ad79 8 #include <malloc.h>
Helmut Tschemernjak 37:77fa81e4ad79 9 #endif
Helmut Tschemernjak 5:c6a960febe80 10
Helmut Tschemernjak 5:c6a960febe80 11 volatile uint32_t PendingInterrupts; // global interrupt mask of received interrupts
Helmut Tschemernjak 5:c6a960febe80 12
Helmut64 0:3b6c2ce051a6 13 time_t cvt_date(char const *date, char const *time);
Helmut64 0:3b6c2ce051a6 14
Helmut Tschemernjak 37:77fa81e4ad79 15 static float GetBrownOutVolt(void);
Helmut Tschemernjak 37:77fa81e4ad79 16
Helmut64 0:3b6c2ce051a6 17 BufferedSerial *ser;
Helmut64 0:3b6c2ce051a6 18 #ifdef FEATURE_USBSERIAL
Helmut64 0:3b6c2ce051a6 19 USBSerialBuffered *usb;
Helmut64 0:3b6c2ce051a6 20 #endif
Helmut64 0:3b6c2ce051a6 21 bool _useDprintf;
Helmut64 0:3b6c2ce051a6 22
Helmut64 0:3b6c2ce051a6 23 void InitSerial(int timeout, DigitalOut *led)
Helmut64 0:3b6c2ce051a6 24 {
Helmut64 0:3b6c2ce051a6 25 _useDprintf = true;
Helmut Tschemernjak 33:617765dcce6c 26 bool uartActive = true;
Helmut Tschemernjak 33:617765dcce6c 27
Helmut64 0:3b6c2ce051a6 28 #ifdef FEATURE_USBSERIAL
Helmut Tschemernjak 33:617765dcce6c 29 DigitalOut rx(USBRX); // need to turn rx low to avoid floating signal
Helmut Tschemernjak 33:617765dcce6c 30 rx = 0;
Helmut Tschemernjak 33:617765dcce6c 31 DigitalIn uartRX(USBRX);
Helmut Tschemernjak 33:617765dcce6c 32 uartActive = uartRX.read();
Helmut64 0:3b6c2ce051a6 33 if (!uartActive) {
Helmut64 0:3b6c2ce051a6 34 usb = new USBSerialBuffered();
Helmut64 0:3b6c2ce051a6 35 Timer t;
Helmut64 0:3b6c2ce051a6 36 t.start();
Helmut64 0:3b6c2ce051a6 37 while(!usb->connected()) {
Helmut64 0:3b6c2ce051a6 38 if (led)
Helmut64 0:3b6c2ce051a6 39 *led = !*led;
Helmut64 0:3b6c2ce051a6 40 wait_ms(100);
Helmut64 0:3b6c2ce051a6 41 if (timeout) {
Helmut Tschemernjak 5:c6a960febe80 42 if (t.read_ms() >= timeout) {
Helmut Tschemernjak 5:c6a960febe80 43 delete usb;
Helmut Tschemernjak 5:c6a960febe80 44 usb = NULL;
Helmut Tschemernjak 5:c6a960febe80 45 DigitalOut rx(USBRX);
Helmut Tschemernjak 5:c6a960febe80 46 rx = 0; // need to turn tx low to avoid floating signal
Helmut Tschemernjak 5:c6a960febe80 47 }
Helmut Tschemernjak 33:617765dcce6c 48 }
Helmut Tschemernjak 33:617765dcce6c 49 }
Helmut Tschemernjak 33:617765dcce6c 50 }
Helmut64 0:3b6c2ce051a6 51 #endif
Helmut Tschemernjak 33:617765dcce6c 52 if (uartActive) {
Helmut64 0:3b6c2ce051a6 53 ser = new BufferedSerial(USBTX, USBRX);
Helmut64 0:3b6c2ce051a6 54 ser->baud(230400);
Helmut64 0:3b6c2ce051a6 55 ser->format(8);
Helmut64 0:3b6c2ce051a6 56 }
Helmut Tschemernjak 33:617765dcce6c 57
Helmut64 0:3b6c2ce051a6 58 time_t t = cvt_date(__DATE__, __TIME__);
Helmut64 0:3b6c2ce051a6 59 if (t > time(NULL)) {
Helmut64 0:3b6c2ce051a6 60 set_time(t);
Helmut64 0:3b6c2ce051a6 61 }
Helmut64 0:3b6c2ce051a6 62 }
Helmut64 0:3b6c2ce051a6 63
Helmut Tschemernjak 37:77fa81e4ad79 64 void RunStartup(void)
Helmut Tschemernjak 37:77fa81e4ad79 65 {
Helmut Tschemernjak 37:77fa81e4ad79 66 rprintf("\r\n");
Helmut Tschemernjak 37:77fa81e4ad79 67 int mbedversion = 9999;
Helmut Tschemernjak 37:77fa81e4ad79 68 #ifdef MBED_LIBRARY_VERSION // not available in mbed head compiles
Helmut Tschemernjak 37:77fa81e4ad79 69 mbedversion = MBED_LIBRARY_VERSION;
Helmut Tschemernjak 37:77fa81e4ad79 70 #endif
Helmut Tschemernjak 37:77fa81e4ad79 71 dprintf("Turtle: %d.%d (%s %s mbed: v%d)", MAJOR_VERSION, MINOR_VERSION, __DATE__, __TIME__, mbedversion);
Helmut Tschemernjak 37:77fa81e4ad79 72
Helmut Tschemernjak 37:77fa81e4ad79 73 dprintf("SysClock: %u Hz.", (unsigned int)SystemCoreClock);
Helmut Tschemernjak 37:77fa81e4ad79 74 #ifdef __ARMCC_VERSION
Helmut Tschemernjak 37:77fa81e4ad79 75 dprintf("ARM Compiler Version: 0x%x", __ARMCC_VERSION);
Helmut Tschemernjak 37:77fa81e4ad79 76 #elif __GNUC__
Helmut Tschemernjak 37:77fa81e4ad79 77 dprintf("GCC Compiler Version: %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
Helmut Tschemernjak 37:77fa81e4ad79 78 #endif
Helmut Tschemernjak 37:77fa81e4ad79 79
Helmut Tschemernjak 37:77fa81e4ad79 80 const char *errstr;
Helmut Tschemernjak 37:77fa81e4ad79 81 if (__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST) != RESET)
Helmut Tschemernjak 37:77fa81e4ad79 82 errstr = "RESET OCCURRED";
Helmut Tschemernjak 37:77fa81e4ad79 83 else
Helmut Tschemernjak 37:77fa81e4ad79 84 errstr = "initalized";
Helmut Tschemernjak 37:77fa81e4ad79 85
Helmut Tschemernjak 37:77fa81e4ad79 86 dprintf("Brown Out Reset %s (%1.1f V)", errstr, GetBrownOutVolt());
Helmut Tschemernjak 37:77fa81e4ad79 87 dprintf("Voltage: %.2f (%s powered)", BatteryVoltage(), BatterySource());
Helmut Tschemernjak 37:77fa81e4ad79 88
Helmut Tschemernjak 37:77fa81e4ad79 89 dprintf("InitDefaults Done");
Helmut Tschemernjak 37:77fa81e4ad79 90 MemoryAvailable(true);
Helmut Tschemernjak 37:77fa81e4ad79 91
Helmut Tschemernjak 37:77fa81e4ad79 92 __HAL_RCC_CLEAR_RESET_FLAGS();
Helmut Tschemernjak 37:77fa81e4ad79 93 }
Helmut64 0:3b6c2ce051a6 94 void printTimeStamp()
Helmut64 0:3b6c2ce051a6 95 {
Helmut64 0:3b6c2ce051a6 96 static LowPowerTimer *timer;
Helmut64 0:3b6c2ce051a6 97 if (!timer) {
Helmut64 0:3b6c2ce051a6 98 timer = new LowPowerTimer();
Helmut64 0:3b6c2ce051a6 99 timer->start();
Helmut64 0:3b6c2ce051a6 100 }
Helmut64 0:3b6c2ce051a6 101 time_t seconds = time(NULL);
Helmut64 0:3b6c2ce051a6 102 struct tm *tm = localtime(&seconds);
Helmut64 0:3b6c2ce051a6 103 int usecs = timer->read_us();
Helmut64 0:3b6c2ce051a6 104 if (usecs < 0) {
Helmut64 0:3b6c2ce051a6 105 usecs = 0;
Helmut64 0:3b6c2ce051a6 106 timer->stop();
Helmut64 0:3b6c2ce051a6 107 timer->reset();
Helmut64 0:3b6c2ce051a6 108 timer->start();
Helmut64 0:3b6c2ce051a6 109 }
Helmut64 0:3b6c2ce051a6 110 int msecs = usecs % 1000000;
Helmut64 0:3b6c2ce051a6 111
Helmut64 0:3b6c2ce051a6 112 rprintf("%02d:%02d:%02d.%06d ", tm->tm_hour, tm->tm_min, tm->tm_sec, msecs);
Helmut64 0:3b6c2ce051a6 113 }
Helmut64 0:3b6c2ce051a6 114
Helmut64 0:3b6c2ce051a6 115 void dprintf(const char *format, ...)
Helmut64 0:3b6c2ce051a6 116 {
Helmut64 0:3b6c2ce051a6 117 std::va_list arg;
Helmut64 0:3b6c2ce051a6 118
Helmut64 0:3b6c2ce051a6 119 va_start(arg, format);
Helmut64 0:3b6c2ce051a6 120 VAprintf(true, true, _useDprintf, format, arg);
Helmut64 0:3b6c2ce051a6 121 va_end(arg);
Helmut64 0:3b6c2ce051a6 122 }
Helmut64 0:3b6c2ce051a6 123
Helmut64 0:3b6c2ce051a6 124 void rprintf(const char *format, ...)
Helmut64 0:3b6c2ce051a6 125 {
Helmut64 0:3b6c2ce051a6 126 std::va_list arg;
Helmut64 0:3b6c2ce051a6 127
Helmut64 0:3b6c2ce051a6 128 va_start(arg, format);
Helmut64 0:3b6c2ce051a6 129 VAprintf(false, false, _useDprintf, format, arg);
Helmut64 0:3b6c2ce051a6 130 va_end(arg);
Helmut64 0:3b6c2ce051a6 131 }
Helmut64 0:3b6c2ce051a6 132
Helmut64 0:3b6c2ce051a6 133 void VAprintf(bool timstamp, bool newline, bool printEnabled, const char *format, va_list arg)
Helmut64 0:3b6c2ce051a6 134 {
Helmut64 0:3b6c2ce051a6 135 if (!printEnabled)
Helmut64 0:3b6c2ce051a6 136 return;
Helmut64 0:3b6c2ce051a6 137
Helmut64 0:3b6c2ce051a6 138 if (timstamp)
Helmut64 0:3b6c2ce051a6 139 printTimeStamp();
Helmut64 0:3b6c2ce051a6 140 #ifdef FEATURE_USBSERIAL
Helmut64 0:3b6c2ce051a6 141 if (usb) {
Helmut64 0:3b6c2ce051a6 142 usb->vprintf_irqsafe(format, arg);
Helmut64 0:3b6c2ce051a6 143 if (newline)
Helmut64 0:3b6c2ce051a6 144 usb->printf_irqsafe("\r\n");
Helmut Tschemernjak 33:617765dcce6c 145 }
Helmut64 0:3b6c2ce051a6 146 #endif
Helmut Tschemernjak 33:617765dcce6c 147 if (ser) {
Helmut64 0:3b6c2ce051a6 148 // serial jas
Helmut64 0:3b6c2ce051a6 149 int r = 0;
Helmut64 0:3b6c2ce051a6 150 r = vsnprintf(NULL, 0, format, arg);
Helmut64 0:3b6c2ce051a6 151 if (r < 82) {
Helmut64 0:3b6c2ce051a6 152 char buffer[82+1];
Helmut64 0:3b6c2ce051a6 153
Helmut64 0:3b6c2ce051a6 154 vsnprintf(buffer, sizeof(buffer), format, arg);
Helmut64 0:3b6c2ce051a6 155 r = ser->write(buffer, r);
Helmut64 0:3b6c2ce051a6 156 } else {
Helmut64 0:3b6c2ce051a6 157 char *buffer = new char[r+1];
Helmut64 0:3b6c2ce051a6 158 if (buffer) {
Helmut64 0:3b6c2ce051a6 159 vsnprintf(buffer, r+1, format, arg);
Helmut64 0:3b6c2ce051a6 160 r = ser->write(buffer, r);
Helmut64 0:3b6c2ce051a6 161 delete[] buffer;
Helmut64 0:3b6c2ce051a6 162 } else {
Helmut64 0:3b6c2ce051a6 163 error("%s %d cannot alloc memory (%d bytes)!\r\n", __FILE__, __LINE__, r+1);
Helmut64 0:3b6c2ce051a6 164 r = 0;
Helmut64 0:3b6c2ce051a6 165 }
Helmut64 0:3b6c2ce051a6 166 }
Helmut64 0:3b6c2ce051a6 167 if (newline)
Helmut64 0:3b6c2ce051a6 168 ser->write("\r\n", 2);
Helmut64 0:3b6c2ce051a6 169 }
Helmut64 0:3b6c2ce051a6 170 }
Helmut64 0:3b6c2ce051a6 171
Helmut Tschemernjak 22:9cca40fcb25e 172 char *ConsoleReadline(char *buf, int buflen, bool echo, int timeout_ms)
Helmut Tschemernjak 14:d9340be18c3d 173 {
Helmut Tschemernjak 14:d9340be18c3d 174 int count = 0;
Helmut Tschemernjak 14:d9340be18c3d 175 memset(buf, 0, buflen);
Helmut Tschemernjak 14:d9340be18c3d 176
Helmut Tschemernjak 33:617765dcce6c 177 #ifdef FEATURE_USBSERIAL
Helmut Tschemernjak 22:9cca40fcb25e 178 if (usb == NULL && ser == NULL)
Helmut Tschemernjak 22:9cca40fcb25e 179 return NULL;
Helmut Tschemernjak 33:617765dcce6c 180 #else
Helmut Tschemernjak 33:617765dcce6c 181 if (ser == NULL)
Helmut Tschemernjak 33:617765dcce6c 182 return NULL;
Helmut Tschemernjak 33:617765dcce6c 183 #endif
Helmut Tschemernjak 22:9cca40fcb25e 184
Helmut Tschemernjak 22:9cca40fcb25e 185 Timer t;
Helmut Tschemernjak 22:9cca40fcb25e 186 int start = 0;
Helmut Tschemernjak 22:9cca40fcb25e 187 if (timeout_ms) {
Helmut Tschemernjak 22:9cca40fcb25e 188 t.start();
Helmut Tschemernjak 22:9cca40fcb25e 189 start = t.read_ms();
Helmut Tschemernjak 22:9cca40fcb25e 190 }
Helmut Tschemernjak 22:9cca40fcb25e 191
Helmut Tschemernjak 33:617765dcce6c 192 #ifdef FEATURE_USBSERIAL
Helmut Tschemernjak 22:9cca40fcb25e 193 if (usb) {
Helmut Tschemernjak 14:d9340be18c3d 194 usb->flush();
Helmut Tschemernjak 14:d9340be18c3d 195 while(usb->readable())
Helmut Tschemernjak 14:d9340be18c3d 196 usb->getc(); // flush old chars
Helmut Tschemernjak 14:d9340be18c3d 197 }
Helmut Tschemernjak 33:617765dcce6c 198 #endif
Helmut Tschemernjak 14:d9340be18c3d 199 if (ser) {
Helmut Tschemernjak 14:d9340be18c3d 200 while(ser->readable())
Helmut Tschemernjak 14:d9340be18c3d 201 ser->getc(); // flush old chars
Helmut Tschemernjak 22:9cca40fcb25e 202 }
Helmut Tschemernjak 14:d9340be18c3d 203
Helmut Tschemernjak 22:9cca40fcb25e 204 while(true) {
Helmut Tschemernjak 22:9cca40fcb25e 205 if (timeout_ms && t.read_ms() - start > timeout_ms)
Helmut Tschemernjak 22:9cca40fcb25e 206 return NULL;
Helmut Tschemernjak 22:9cca40fcb25e 207 int c = -2;
Helmut Tschemernjak 33:617765dcce6c 208 #ifdef FEATURE_USBSERIAL
Helmut Tschemernjak 22:9cca40fcb25e 209 if (usb && usb->readable())
Helmut Tschemernjak 22:9cca40fcb25e 210 c = usb->getc();
Helmut Tschemernjak 33:617765dcce6c 211 #endif
Helmut Tschemernjak 22:9cca40fcb25e 212 if (ser && ser->readable())
Helmut Tschemernjak 22:9cca40fcb25e 213 c = ser->getc();
Helmut Tschemernjak 22:9cca40fcb25e 214 if (c == -2)
Helmut Tschemernjak 22:9cca40fcb25e 215 continue;
Helmut Tschemernjak 22:9cca40fcb25e 216
Helmut Tschemernjak 22:9cca40fcb25e 217 if (c == 0 || c == -1 || c == '\r' || c == '\n' || c == 3 || c == 4)
Helmut Tschemernjak 22:9cca40fcb25e 218 break;
Helmut Tschemernjak 22:9cca40fcb25e 219 if (c == '\b' || c == 0x7f) { // backspace
Helmut Tschemernjak 22:9cca40fcb25e 220 if (count < 1)
Helmut Tschemernjak 22:9cca40fcb25e 221 continue;
Helmut Tschemernjak 22:9cca40fcb25e 222 buf[--count] = 0;
Helmut Tschemernjak 22:9cca40fcb25e 223 if (echo)
Helmut Tschemernjak 22:9cca40fcb25e 224 rprintf("\b \b");
Helmut Tschemernjak 33:617765dcce6c 225 #ifdef FEATURE_USBSERIAL
Helmut Tschemernjak 22:9cca40fcb25e 226 if (usb)
Helmut Tschemernjak 22:9cca40fcb25e 227 usb->flush();
Helmut Tschemernjak 33:617765dcce6c 228 #endif
Helmut Tschemernjak 22:9cca40fcb25e 229 continue;
Helmut Tschemernjak 14:d9340be18c3d 230 }
Helmut Tschemernjak 22:9cca40fcb25e 231 if (echo) {
Helmut Tschemernjak 22:9cca40fcb25e 232 rprintf("%c", c);
Helmut Tschemernjak 33:617765dcce6c 233 #ifdef FEATURE_USBSERIAL
Helmut Tschemernjak 22:9cca40fcb25e 234 if (usb)
Helmut Tschemernjak 22:9cca40fcb25e 235 usb->flush();
Helmut Tschemernjak 33:617765dcce6c 236 #endif
Helmut Tschemernjak 22:9cca40fcb25e 237 }
Helmut Tschemernjak 22:9cca40fcb25e 238
Helmut Tschemernjak 33:617765dcce6c 239 start = t.read_ms();
Helmut Tschemernjak 22:9cca40fcb25e 240 buf[count] = c;
Helmut Tschemernjak 22:9cca40fcb25e 241 if (count++ >= buflen-2)
Helmut Tschemernjak 22:9cca40fcb25e 242 break;
Helmut Tschemernjak 22:9cca40fcb25e 243 // dprintf("Got char: '%c'(%d)", c, c);
Helmut Tschemernjak 14:d9340be18c3d 244 }
Helmut Tschemernjak 22:9cca40fcb25e 245
Helmut Tschemernjak 14:d9340be18c3d 246 if (echo)
Helmut Tschemernjak 14:d9340be18c3d 247 rprintf("\r\n");
Helmut Tschemernjak 14:d9340be18c3d 248 if (count)
Helmut Tschemernjak 14:d9340be18c3d 249 return buf;
Helmut Tschemernjak 14:d9340be18c3d 250 return NULL;
Helmut Tschemernjak 14:d9340be18c3d 251 }
Helmut Tschemernjak 14:d9340be18c3d 252
Helmut64 0:3b6c2ce051a6 253
Helmut64 30:8bc655c9b224 254 void dump(const char *title, void *data, int len)
Helmut64 30:8bc655c9b224 255 {
Helmut64 30:8bc655c9b224 256 dump(title, data, len, false);
Helmut64 30:8bc655c9b224 257 }
Helmut64 30:8bc655c9b224 258
Helmut64 0:3b6c2ce051a6 259 void dump(const char *title, const void *data, int len, bool dwords)
Helmut64 0:3b6c2ce051a6 260 {
Helmut Tschemernjak 14:d9340be18c3d 261 dprintf("dump(\"%s\", 0x%x, %d bytes)", title, (unsigned int)data, len);
Helmut64 0:3b6c2ce051a6 262
Helmut64 0:3b6c2ce051a6 263 int i, j, cnt;
Helmut64 0:3b6c2ce051a6 264 unsigned char *u;
Helmut64 0:3b6c2ce051a6 265 const int width = 16;
Helmut64 0:3b6c2ce051a6 266 const int seppos = 7;
Helmut64 0:3b6c2ce051a6 267
Helmut64 0:3b6c2ce051a6 268 cnt = 0;
Helmut64 0:3b6c2ce051a6 269 u = (unsigned char *)data;
Helmut64 0:3b6c2ce051a6 270 while (len > 0) {
Helmut64 0:3b6c2ce051a6 271 rprintf("%08x: ", (unsigned int)data + cnt);
Helmut64 0:3b6c2ce051a6 272 if (dwords) {
Helmut64 0:3b6c2ce051a6 273 unsigned int *ip = ( unsigned int *)u;
Helmut64 0:3b6c2ce051a6 274 rprintf(" 0x%08x\r\n", *ip);
Helmut64 0:3b6c2ce051a6 275 u+= 4;
Helmut64 0:3b6c2ce051a6 276 len -= 4;
Helmut64 0:3b6c2ce051a6 277 cnt += 4;
Helmut64 0:3b6c2ce051a6 278 continue;
Helmut64 0:3b6c2ce051a6 279 }
Helmut64 0:3b6c2ce051a6 280 cnt += width;
Helmut64 0:3b6c2ce051a6 281 j = len < width ? len : width;
Helmut64 0:3b6c2ce051a6 282 for (i = 0; i < j; i++) {
Helmut64 0:3b6c2ce051a6 283 rprintf("%2.2x ", *(u + i));
Helmut64 0:3b6c2ce051a6 284 if (i == seppos)
Helmut64 0:3b6c2ce051a6 285 rprintf(" ");
Helmut64 0:3b6c2ce051a6 286 }
Helmut64 0:3b6c2ce051a6 287 rprintf(" ");
Helmut64 0:3b6c2ce051a6 288 if (j < width) {
Helmut64 0:3b6c2ce051a6 289 i = width - j;
Helmut64 0:3b6c2ce051a6 290 if (i > seppos + 1)
Helmut64 0:3b6c2ce051a6 291 rprintf(" ");
Helmut64 0:3b6c2ce051a6 292 while (i--) {
Helmut64 0:3b6c2ce051a6 293 rprintf("%s", " ");
Helmut64 0:3b6c2ce051a6 294 }
Helmut64 0:3b6c2ce051a6 295 }
Helmut64 0:3b6c2ce051a6 296 for (i = 0; i < j; i++) {
Helmut64 0:3b6c2ce051a6 297 int c = *(u + i);
Helmut64 0:3b6c2ce051a6 298 if (c >= ' ' && c <= '~')
Helmut64 0:3b6c2ce051a6 299 rprintf("%c", c);
Helmut64 0:3b6c2ce051a6 300 else
Helmut64 0:3b6c2ce051a6 301 rprintf(".");
Helmut64 0:3b6c2ce051a6 302 if (i == seppos)
Helmut64 0:3b6c2ce051a6 303 rprintf(" ");
Helmut64 0:3b6c2ce051a6 304 }
Helmut64 0:3b6c2ce051a6 305 len -= width;
Helmut64 0:3b6c2ce051a6 306 u += width;
Helmut64 0:3b6c2ce051a6 307 rprintf("\r\n");
Helmut Tschemernjak 22:9cca40fcb25e 308 if (ser)
Helmut Tschemernjak 22:9cca40fcb25e 309 wait_ms(5); // give the serial some time.
Helmut64 0:3b6c2ce051a6 310 }
Helmut64 0:3b6c2ce051a6 311 rprintf("--\r\n");
Helmut64 0:3b6c2ce051a6 312 }
Helmut64 0:3b6c2ce051a6 313
Helmut64 0:3b6c2ce051a6 314 /*
Helmut64 0:3b6c2ce051a6 315 * Convert compile time to system time
Helmut64 0:3b6c2ce051a6 316 */
Helmut64 0:3b6c2ce051a6 317 time_t
Helmut64 0:3b6c2ce051a6 318 cvt_date(char const *date, char const *time)
Helmut64 0:3b6c2ce051a6 319 {
Helmut64 0:3b6c2ce051a6 320 char s_month[5];
Helmut64 0:3b6c2ce051a6 321 int year;
Helmut64 0:3b6c2ce051a6 322 struct tm t;
Helmut64 0:3b6c2ce051a6 323 static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
Helmut64 0:3b6c2ce051a6 324 sscanf(date, "%s %d %d", s_month, &t.tm_mday, &year);
Helmut64 0:3b6c2ce051a6 325 sscanf(time, "%2d %*c %2d %*c %2d", &t.tm_hour, &t.tm_min, &t.tm_sec);
Helmut64 0:3b6c2ce051a6 326 // Find where is s_month in month_names. Deduce month value.
Helmut64 0:3b6c2ce051a6 327 t.tm_mon = (strstr(month_names, s_month) - month_names) / 3;
Helmut64 0:3b6c2ce051a6 328 t.tm_year = year - 1900;
Helmut64 0:3b6c2ce051a6 329 return (int)mktime(&t);
Helmut64 0:3b6c2ce051a6 330 }
Helmut Tschemernjak 1:56fdc660a26a 331
Helmut Tschemernjak 1:56fdc660a26a 332
Helmut Tschemernjak 1:56fdc660a26a 333
Helmut Tschemernjak 1:56fdc660a26a 334 void InterrruptMSG(enum InterrruptDevice irqid) {
Helmut Tschemernjak 1:56fdc660a26a 335 help_atomic_or_relaxed(&PendingInterrupts, irqid);
Helmut Tschemernjak 1:56fdc660a26a 336 }
Helmut Tschemernjak 1:56fdc660a26a 337
Helmut Tschemernjak 1:56fdc660a26a 338
Helmut Tschemernjak 1:56fdc660a26a 339 uint32_t readclrPendingInterrupts() {
Helmut Tschemernjak 1:56fdc660a26a 340 return help_atomic_readclr_relaxed(&PendingInterrupts);
Helmut Tschemernjak 1:56fdc660a26a 341 }
Helmut Tschemernjak 1:56fdc660a26a 342
Helmut Tschemernjak 1:56fdc660a26a 343 uint32_t readPendingInterrupts() {
Helmut Tschemernjak 1:56fdc660a26a 344 return help_atomic_load_relaxed(&PendingInterrupts);
Helmut Tschemernjak 1:56fdc660a26a 345 }
Helmut Tschemernjak 1:56fdc660a26a 346
Helmut Tschemernjak 1:56fdc660a26a 347 const char *
Helmut Tschemernjak 1:56fdc660a26a 348 BatterySource(void)
Helmut Tschemernjak 1:56fdc660a26a 349 {
Helmut Tschemernjak 1:56fdc660a26a 350 const char *pwrSource = "Battery";
Helmut Tschemernjak 1:56fdc660a26a 351 #ifdef BATPOWER_EN
Helmut Tschemernjak 1:56fdc660a26a 352 {
Helmut Tschemernjak 1:56fdc660a26a 353 DigitalIn pwr(BATPOWER_EN);
Helmut Tschemernjak 1:56fdc660a26a 354 if (pwr == BATPOWER_EXT)
Helmut Tschemernjak 1:56fdc660a26a 355 pwrSource = "USB";
Helmut Tschemernjak 1:56fdc660a26a 356 }
Helmut Tschemernjak 1:56fdc660a26a 357 #endif
Helmut Tschemernjak 1:56fdc660a26a 358 return pwrSource;
Helmut Tschemernjak 1:56fdc660a26a 359 }
Helmut Tschemernjak 1:56fdc660a26a 360
Helmut Tschemernjak 22:9cca40fcb25e 361
Helmut Tschemernjak 37:77fa81e4ad79 362 float
Helmut Tschemernjak 37:77fa81e4ad79 363 GetBrownOutVolt(void)
Helmut Tschemernjak 37:77fa81e4ad79 364 {
Helmut Tschemernjak 37:77fa81e4ad79 365 unsigned int *FlashOptionRegister = (unsigned int *)0x1FFF7800;
Helmut Tschemernjak 37:77fa81e4ad79 366
Helmut Tschemernjak 37:77fa81e4ad79 367 int val = *FlashOptionRegister >> 8 & 0x7; // masking out the BOR bits 9-11
Helmut Tschemernjak 37:77fa81e4ad79 368 switch(val) {
Helmut Tschemernjak 37:77fa81e4ad79 369 case 0:
Helmut Tschemernjak 38:1f3792d6f9ec 370 return 1.7;
Helmut Tschemernjak 37:77fa81e4ad79 371 case 1:
Helmut Tschemernjak 38:1f3792d6f9ec 372 return 2.0;
Helmut Tschemernjak 37:77fa81e4ad79 373 case 2:
Helmut Tschemernjak 38:1f3792d6f9ec 374 return 2.2;
Helmut Tschemernjak 37:77fa81e4ad79 375 case 3:
Helmut Tschemernjak 38:1f3792d6f9ec 376 return 2.5;
Helmut Tschemernjak 37:77fa81e4ad79 377 case 4:
Helmut Tschemernjak 38:1f3792d6f9ec 378 return 2.8;
Helmut Tschemernjak 37:77fa81e4ad79 379 default:
Helmut Tschemernjak 38:1f3792d6f9ec 380 return 999;
Helmut Tschemernjak 37:77fa81e4ad79 381 }
Helmut Tschemernjak 37:77fa81e4ad79 382 }
Helmut Tschemernjak 37:77fa81e4ad79 383
Helmut Tschemernjak 22:9cca40fcb25e 384 void MCUReset(void)
Helmut Tschemernjak 22:9cca40fcb25e 385 {
Helmut Tschemernjak 22:9cca40fcb25e 386 #define AIRCR_VECTKEY_MASK 0x05FA0000
Helmut Tschemernjak 22:9cca40fcb25e 387 SCB->AIRCR = AIRCR_VECTKEY_MASK | 0x04; // NVIC_GenerateSystemReset();
Helmut Tschemernjak 22:9cca40fcb25e 388 }
Helmut Tschemernjak 22:9cca40fcb25e 389
Helmut Tschemernjak 38:1f3792d6f9ec 390
Helmut Tschemernjak 38:1f3792d6f9ec 391 #define FREEMEM_CELL 100
Helmut Tschemernjak 38:1f3792d6f9ec 392
Helmut Tschemernjak 38:1f3792d6f9ec 393 struct elem { /* Definition of a structure that is FREEMEM_CELL bytes in size.) */
Helmut Tschemernjak 38:1f3792d6f9ec 394 struct elem *next;
Helmut Tschemernjak 38:1f3792d6f9ec 395 char dummy[FREEMEM_CELL-2];
Helmut Tschemernjak 38:1f3792d6f9ec 396 };
Helmut Tschemernjak 38:1f3792d6f9ec 397
Helmut Tschemernjak 37:77fa81e4ad79 398 size_t
Helmut Tschemernjak 37:77fa81e4ad79 399 MemoryAvailable(bool print)
Helmut Tschemernjak 37:77fa81e4ad79 400 {
Helmut Tschemernjak 37:77fa81e4ad79 401 size_t counter;
Helmut Tschemernjak 37:77fa81e4ad79 402 #ifdef TOOLCHAIN_GCC
Helmut Tschemernjak 37:77fa81e4ad79 403 struct mallinfo mi = mallinfo();
Helmut Tschemernjak 37:77fa81e4ad79 404 extern char end[];
Helmut Tschemernjak 37:77fa81e4ad79 405 extern char _estack[];
Helmut Tschemernjak 37:77fa81e4ad79 406 counter = (_estack - end) - mi.uordblks;
Helmut Tschemernjak 37:77fa81e4ad79 407 if (print)
Helmut Tschemernjak 37:77fa81e4ad79 408 dprintf("MemoryAvailable: %d kB (%d bytes)", counter/1024, counter);
Helmut Tschemernjak 37:77fa81e4ad79 409 return counter;
Helmut Tschemernjak 37:77fa81e4ad79 410 #else
Helmut Tschemernjak 37:77fa81e4ad79 411 struct elem *head, *current, *nextone;
Helmut Tschemernjak 37:77fa81e4ad79 412 current = head = (struct elem*) malloc(sizeof(struct elem));
Helmut Tschemernjak 37:77fa81e4ad79 413 if (head == NULL)
Helmut Tschemernjak 37:77fa81e4ad79 414 return 0; /*No memory available.*/
Helmut Tschemernjak 37:77fa81e4ad79 415 counter = 0;
Helmut Tschemernjak 37:77fa81e4ad79 416 // __disable_irq();
Helmut Tschemernjak 37:77fa81e4ad79 417 do {
Helmut Tschemernjak 37:77fa81e4ad79 418 counter++;
Helmut Tschemernjak 37:77fa81e4ad79 419 current->next = (struct elem*) malloc(sizeof(struct elem));
Helmut Tschemernjak 37:77fa81e4ad79 420 current = current->next;
Helmut Tschemernjak 37:77fa81e4ad79 421 } while (current != NULL);
Helmut Tschemernjak 37:77fa81e4ad79 422 /* Now counter holds the number of type elem
Helmut Tschemernjak 37:77fa81e4ad79 423 structures we were able to allocate. We
Helmut Tschemernjak 37:77fa81e4ad79 424 must free them all before returning. */
Helmut Tschemernjak 37:77fa81e4ad79 425 current = head;
Helmut Tschemernjak 37:77fa81e4ad79 426 do {
Helmut Tschemernjak 37:77fa81e4ad79 427 nextone = current->next;
Helmut Tschemernjak 37:77fa81e4ad79 428 free(current);
Helmut Tschemernjak 37:77fa81e4ad79 429 current = nextone;
Helmut Tschemernjak 37:77fa81e4ad79 430 } while (nextone != NULL);
Helmut Tschemernjak 37:77fa81e4ad79 431 // __enable_irq();
Helmut Tschemernjak 37:77fa81e4ad79 432
Helmut Tschemernjak 37:77fa81e4ad79 433 if (print)
Helmut Tschemernjak 37:77fa81e4ad79 434 dprintf("MemoryAvailable: %d kB (%d bytes)", (counter*FREEMEM_CELL)/1024, counter*FREEMEM_CELL);
Helmut Tschemernjak 37:77fa81e4ad79 435 return counter*FREEMEM_CELL;
Helmut Tschemernjak 37:77fa81e4ad79 436 #endif
Helmut Tschemernjak 37:77fa81e4ad79 437 }
Helmut Tschemernjak 37:77fa81e4ad79 438
Helmut Tschemernjak 37:77fa81e4ad79 439
Helmut Tschemernjak 37:77fa81e4ad79 440 static const char *cmds = \
Helmut Tschemernjak 37:77fa81e4ad79 441 "\r\nThe following commands are available:\r\n\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 442 " p -- Property Editor\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 443 " t -- LoRa PingPong Test\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 444 " d -- Hexdump of memory address [offset count]\r\n"
Helmut Tschemernjak 37:77fa81e4ad79 445 " r -- Reset\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 446 " c -- Continue with RadioShuttle\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 447 "\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 448 "waiting 10 secs ...\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 449 "\r\n";
Helmut Tschemernjak 37:77fa81e4ad79 450
Helmut Tschemernjak 37:77fa81e4ad79 451 void RunCommands(int timeout_ms) {
Helmut Tschemernjak 37:77fa81e4ad79 452 bool cmdLoop = true;
Helmut Tschemernjak 37:77fa81e4ad79 453 while(cmdLoop) {
Helmut Tschemernjak 37:77fa81e4ad79 454 char buf[32];
Helmut Tschemernjak 37:77fa81e4ad79 455
Helmut Tschemernjak 37:77fa81e4ad79 456 rprintf(cmds);
Helmut Tschemernjak 37:77fa81e4ad79 457 rprintf("Turtle$ ");
Helmut Tschemernjak 37:77fa81e4ad79 458 if (ConsoleReadline(buf, sizeof(buf), true, timeout_ms) == NULL) {
Helmut Tschemernjak 37:77fa81e4ad79 459 cmdLoop = false;
Helmut Tschemernjak 37:77fa81e4ad79 460 break;
Helmut Tschemernjak 37:77fa81e4ad79 461 }
Helmut Tschemernjak 37:77fa81e4ad79 462 switch(buf[0]) {
Helmut Tschemernjak 37:77fa81e4ad79 463 case 'p':
Helmut Tschemernjak 37:77fa81e4ad79 464 case 'P':
Helmut Tschemernjak 37:77fa81e4ad79 465 #ifdef FEATURE_NVPROPERTYEDITOR
Helmut Tschemernjak 37:77fa81e4ad79 466 NVPropertyEditor();
Helmut Tschemernjak 37:77fa81e4ad79 467 #endif
Helmut Tschemernjak 37:77fa81e4ad79 468 break;
Helmut Tschemernjak 37:77fa81e4ad79 469 case 't':
Helmut Tschemernjak 37:77fa81e4ad79 470 case 'T':
Helmut Tschemernjak 37:77fa81e4ad79 471 #ifdef FEATURE_LORA_PING_PONG
Helmut Tschemernjak 37:77fa81e4ad79 472 SX1276PingPong(); // basic LoRa raw ping/pong without RadioShuttle
Helmut Tschemernjak 37:77fa81e4ad79 473 #endif
Helmut Tschemernjak 37:77fa81e4ad79 474 break;
Helmut Tschemernjak 37:77fa81e4ad79 475 case 'r':
Helmut Tschemernjak 37:77fa81e4ad79 476 case 'R':
Helmut Tschemernjak 37:77fa81e4ad79 477 MCUReset();
Helmut Tschemernjak 37:77fa81e4ad79 478 break;
Helmut Tschemernjak 37:77fa81e4ad79 479 case 'd':
Helmut Tschemernjak 37:77fa81e4ad79 480 case 'D':
Helmut Tschemernjak 37:77fa81e4ad79 481 {
Helmut Tschemernjak 37:77fa81e4ad79 482 char *addr = strchr(buf, ' ');
Helmut Tschemernjak 37:77fa81e4ad79 483 if (addr) {
Helmut Tschemernjak 37:77fa81e4ad79 484 *addr++ = 0;
Helmut Tschemernjak 37:77fa81e4ad79 485 char *length = strchr(addr, ' ');
Helmut Tschemernjak 37:77fa81e4ad79 486 if (length) {
Helmut Tschemernjak 37:77fa81e4ad79 487 *length++ = 0;
Helmut Tschemernjak 37:77fa81e4ad79 488 }
Helmut Tschemernjak 37:77fa81e4ad79 489 unsigned long address = strtoll(addr, NULL, 0);
Helmut Tschemernjak 37:77fa81e4ad79 490 unsigned long cnt = 32;
Helmut Tschemernjak 37:77fa81e4ad79 491 if (length)
Helmut Tschemernjak 37:77fa81e4ad79 492 cnt = strtoll(length, NULL, 0);
Helmut Tschemernjak 37:77fa81e4ad79 493 dump("Hexdump", (void *)address, cnt);
Helmut Tschemernjak 37:77fa81e4ad79 494 }
Helmut Tschemernjak 37:77fa81e4ad79 495 }
Helmut Tschemernjak 37:77fa81e4ad79 496 break;
Helmut Tschemernjak 37:77fa81e4ad79 497 case 'c':
Helmut Tschemernjak 37:77fa81e4ad79 498 case 'C':
Helmut Tschemernjak 37:77fa81e4ad79 499 cmdLoop = false;
Helmut Tschemernjak 37:77fa81e4ad79 500 break;
Helmut Tschemernjak 37:77fa81e4ad79 501 default:
Helmut Tschemernjak 37:77fa81e4ad79 502 break;
Helmut Tschemernjak 37:77fa81e4ad79 503 }
Helmut Tschemernjak 37:77fa81e4ad79 504 }
Helmut Tschemernjak 37:77fa81e4ad79 505 rprintf("\r\n");
Helmut Tschemernjak 37:77fa81e4ad79 506
Helmut Tschemernjak 37:77fa81e4ad79 507 }