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:
Thu Jun 06 09:31:08 2019 +0200
Revision:
62:86aaaf9fa55d
Parent:
54:28ed5c68e5f6
Updated OLED lib

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