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:10:17 2019 +0100
Revision:
37:77fa81e4ad79
Parent:
33:617765dcce6c
Child:
38:1f3792d6f9ec
Added a local RadioTestSample.cpp
Moved commands into RunCommands function
Added RunStartup function to provide proper startup messages

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 float borVolt;
Helmut Tschemernjak 37:77fa81e4ad79 366 unsigned int *FlashOptionRegister = (unsigned int *)0x1FFF7800;
Helmut Tschemernjak 37:77fa81e4ad79 367
Helmut Tschemernjak 37:77fa81e4ad79 368 int val = *FlashOptionRegister >> 8 & 0x7; // masking out the BOR bits 9-11
Helmut Tschemernjak 37:77fa81e4ad79 369 switch(val) {
Helmut Tschemernjak 37:77fa81e4ad79 370 case 0:
Helmut Tschemernjak 37:77fa81e4ad79 371 return borVolt = 1.7;
Helmut Tschemernjak 37:77fa81e4ad79 372 case 1:
Helmut Tschemernjak 37:77fa81e4ad79 373 return borVolt = 2.0;
Helmut Tschemernjak 37:77fa81e4ad79 374 case 2:
Helmut Tschemernjak 37:77fa81e4ad79 375 return borVolt = 2.2;
Helmut Tschemernjak 37:77fa81e4ad79 376 case 3:
Helmut Tschemernjak 37:77fa81e4ad79 377 return borVolt = 2.5;
Helmut Tschemernjak 37:77fa81e4ad79 378 case 4:
Helmut Tschemernjak 37:77fa81e4ad79 379 return borVolt = 2.8;
Helmut Tschemernjak 37:77fa81e4ad79 380 default:
Helmut Tschemernjak 37:77fa81e4ad79 381 return borVolt = 999;
Helmut Tschemernjak 37:77fa81e4ad79 382 }
Helmut Tschemernjak 37:77fa81e4ad79 383 }
Helmut Tschemernjak 37:77fa81e4ad79 384
Helmut Tschemernjak 22:9cca40fcb25e 385 void MCUReset(void)
Helmut Tschemernjak 22:9cca40fcb25e 386 {
Helmut Tschemernjak 22:9cca40fcb25e 387 #define AIRCR_VECTKEY_MASK 0x05FA0000
Helmut Tschemernjak 22:9cca40fcb25e 388 SCB->AIRCR = AIRCR_VECTKEY_MASK | 0x04; // NVIC_GenerateSystemReset();
Helmut Tschemernjak 22:9cca40fcb25e 389 }
Helmut Tschemernjak 22:9cca40fcb25e 390
Helmut Tschemernjak 37:77fa81e4ad79 391 size_t
Helmut Tschemernjak 37:77fa81e4ad79 392 MemoryAvailable(bool print)
Helmut Tschemernjak 37:77fa81e4ad79 393 {
Helmut Tschemernjak 37:77fa81e4ad79 394 size_t counter;
Helmut Tschemernjak 37:77fa81e4ad79 395 #ifdef TOOLCHAIN_GCC
Helmut Tschemernjak 37:77fa81e4ad79 396 struct mallinfo mi = mallinfo();
Helmut Tschemernjak 37:77fa81e4ad79 397 extern char end[];
Helmut Tschemernjak 37:77fa81e4ad79 398 extern char _estack[];
Helmut Tschemernjak 37:77fa81e4ad79 399 counter = (_estack - end) - mi.uordblks;
Helmut Tschemernjak 37:77fa81e4ad79 400 if (print)
Helmut Tschemernjak 37:77fa81e4ad79 401 dprintf("MemoryAvailable: %d kB (%d bytes)", counter/1024, counter);
Helmut Tschemernjak 37:77fa81e4ad79 402 return counter;
Helmut Tschemernjak 37:77fa81e4ad79 403 #else
Helmut Tschemernjak 37:77fa81e4ad79 404 struct elem *head, *current, *nextone;
Helmut Tschemernjak 37:77fa81e4ad79 405 current = head = (struct elem*) malloc(sizeof(struct elem));
Helmut Tschemernjak 37:77fa81e4ad79 406 if (head == NULL)
Helmut Tschemernjak 37:77fa81e4ad79 407 return 0; /*No memory available.*/
Helmut Tschemernjak 37:77fa81e4ad79 408 counter = 0;
Helmut Tschemernjak 37:77fa81e4ad79 409 // __disable_irq();
Helmut Tschemernjak 37:77fa81e4ad79 410 do {
Helmut Tschemernjak 37:77fa81e4ad79 411 counter++;
Helmut Tschemernjak 37:77fa81e4ad79 412 current->next = (struct elem*) malloc(sizeof(struct elem));
Helmut Tschemernjak 37:77fa81e4ad79 413 current = current->next;
Helmut Tschemernjak 37:77fa81e4ad79 414 } while (current != NULL);
Helmut Tschemernjak 37:77fa81e4ad79 415 /* Now counter holds the number of type elem
Helmut Tschemernjak 37:77fa81e4ad79 416 structures we were able to allocate. We
Helmut Tschemernjak 37:77fa81e4ad79 417 must free them all before returning. */
Helmut Tschemernjak 37:77fa81e4ad79 418 current = head;
Helmut Tschemernjak 37:77fa81e4ad79 419 do {
Helmut Tschemernjak 37:77fa81e4ad79 420 nextone = current->next;
Helmut Tschemernjak 37:77fa81e4ad79 421 free(current);
Helmut Tschemernjak 37:77fa81e4ad79 422 current = nextone;
Helmut Tschemernjak 37:77fa81e4ad79 423 } while (nextone != NULL);
Helmut Tschemernjak 37:77fa81e4ad79 424 // __enable_irq();
Helmut Tschemernjak 37:77fa81e4ad79 425
Helmut Tschemernjak 37:77fa81e4ad79 426 if (print)
Helmut Tschemernjak 37:77fa81e4ad79 427 dprintf("MemoryAvailable: %d kB (%d bytes)", (counter*FREEMEM_CELL)/1024, counter*FREEMEM_CELL);
Helmut Tschemernjak 37:77fa81e4ad79 428 return counter*FREEMEM_CELL;
Helmut Tschemernjak 37:77fa81e4ad79 429 #endif
Helmut Tschemernjak 37:77fa81e4ad79 430 }
Helmut Tschemernjak 37:77fa81e4ad79 431
Helmut Tschemernjak 37:77fa81e4ad79 432
Helmut Tschemernjak 37:77fa81e4ad79 433 static const char *cmds = \
Helmut Tschemernjak 37:77fa81e4ad79 434 "\r\nThe following commands are available:\r\n\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 435 " p -- Property Editor\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 436 " t -- LoRa PingPong Test\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 437 " d -- Hexdump of memory address [offset count]\r\n"
Helmut Tschemernjak 37:77fa81e4ad79 438 " r -- Reset\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 439 " c -- Continue with RadioShuttle\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 440 "\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 441 "waiting 10 secs ...\r\n" \
Helmut Tschemernjak 37:77fa81e4ad79 442 "\r\n";
Helmut Tschemernjak 37:77fa81e4ad79 443
Helmut Tschemernjak 37:77fa81e4ad79 444 void RunCommands(int timeout_ms) {
Helmut Tschemernjak 37:77fa81e4ad79 445 bool cmdLoop = true;
Helmut Tschemernjak 37:77fa81e4ad79 446 while(cmdLoop) {
Helmut Tschemernjak 37:77fa81e4ad79 447 char buf[32];
Helmut Tschemernjak 37:77fa81e4ad79 448
Helmut Tschemernjak 37:77fa81e4ad79 449 rprintf(cmds);
Helmut Tschemernjak 37:77fa81e4ad79 450 rprintf("Turtle$ ");
Helmut Tschemernjak 37:77fa81e4ad79 451 if (ConsoleReadline(buf, sizeof(buf), true, timeout_ms) == NULL) {
Helmut Tschemernjak 37:77fa81e4ad79 452 cmdLoop = false;
Helmut Tschemernjak 37:77fa81e4ad79 453 break;
Helmut Tschemernjak 37:77fa81e4ad79 454 }
Helmut Tschemernjak 37:77fa81e4ad79 455 switch(buf[0]) {
Helmut Tschemernjak 37:77fa81e4ad79 456 case 'p':
Helmut Tschemernjak 37:77fa81e4ad79 457 case 'P':
Helmut Tschemernjak 37:77fa81e4ad79 458 #ifdef FEATURE_NVPROPERTYEDITOR
Helmut Tschemernjak 37:77fa81e4ad79 459 NVPropertyEditor();
Helmut Tschemernjak 37:77fa81e4ad79 460 #endif
Helmut Tschemernjak 37:77fa81e4ad79 461 break;
Helmut Tschemernjak 37:77fa81e4ad79 462 case 't':
Helmut Tschemernjak 37:77fa81e4ad79 463 case 'T':
Helmut Tschemernjak 37:77fa81e4ad79 464 #ifdef FEATURE_LORA_PING_PONG
Helmut Tschemernjak 37:77fa81e4ad79 465 SX1276PingPong(); // basic LoRa raw ping/pong without RadioShuttle
Helmut Tschemernjak 37:77fa81e4ad79 466 #endif
Helmut Tschemernjak 37:77fa81e4ad79 467 break;
Helmut Tschemernjak 37:77fa81e4ad79 468 case 'r':
Helmut Tschemernjak 37:77fa81e4ad79 469 case 'R':
Helmut Tschemernjak 37:77fa81e4ad79 470 MCUReset();
Helmut Tschemernjak 37:77fa81e4ad79 471 break;
Helmut Tschemernjak 37:77fa81e4ad79 472 case 'd':
Helmut Tschemernjak 37:77fa81e4ad79 473 case 'D':
Helmut Tschemernjak 37:77fa81e4ad79 474 {
Helmut Tschemernjak 37:77fa81e4ad79 475 char *addr = strchr(buf, ' ');
Helmut Tschemernjak 37:77fa81e4ad79 476 if (addr) {
Helmut Tschemernjak 37:77fa81e4ad79 477 *addr++ = 0;
Helmut Tschemernjak 37:77fa81e4ad79 478 char *length = strchr(addr, ' ');
Helmut Tschemernjak 37:77fa81e4ad79 479 if (length) {
Helmut Tschemernjak 37:77fa81e4ad79 480 *length++ = 0;
Helmut Tschemernjak 37:77fa81e4ad79 481 }
Helmut Tschemernjak 37:77fa81e4ad79 482 unsigned long address = strtoll(addr, NULL, 0);
Helmut Tschemernjak 37:77fa81e4ad79 483 unsigned long cnt = 32;
Helmut Tschemernjak 37:77fa81e4ad79 484 if (length)
Helmut Tschemernjak 37:77fa81e4ad79 485 cnt = strtoll(length, NULL, 0);
Helmut Tschemernjak 37:77fa81e4ad79 486 dump("Hexdump", (void *)address, cnt);
Helmut Tschemernjak 37:77fa81e4ad79 487 }
Helmut Tschemernjak 37:77fa81e4ad79 488 }
Helmut Tschemernjak 37:77fa81e4ad79 489 break;
Helmut Tschemernjak 37:77fa81e4ad79 490 case 'c':
Helmut Tschemernjak 37:77fa81e4ad79 491 case 'C':
Helmut Tschemernjak 37:77fa81e4ad79 492 cmdLoop = false;
Helmut Tschemernjak 37:77fa81e4ad79 493 break;
Helmut Tschemernjak 37:77fa81e4ad79 494 default:
Helmut Tschemernjak 37:77fa81e4ad79 495 break;
Helmut Tschemernjak 37:77fa81e4ad79 496 }
Helmut Tschemernjak 37:77fa81e4ad79 497 }
Helmut Tschemernjak 37:77fa81e4ad79 498 rprintf("\r\n");
Helmut Tschemernjak 37:77fa81e4ad79 499
Helmut Tschemernjak 37:77fa81e4ad79 500 }