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:
Fri Jan 25 17:16:41 2019 +0100
Revision:
14:d9340be18c3d
Parent:
5:c6a960febe80
Child:
16:c12c85fdfa60
Added ConsoleReadline function for the serial and USB console

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 5:c6a960febe80 6
Helmut Tschemernjak 5:c6a960febe80 7 volatile uint32_t PendingInterrupts; // global interrupt mask of received interrupts
Helmut Tschemernjak 5:c6a960febe80 8
Helmut64 0:3b6c2ce051a6 9 time_t cvt_date(char const *date, char const *time);
Helmut64 0:3b6c2ce051a6 10
Helmut64 0:3b6c2ce051a6 11 BufferedSerial *ser;
Helmut64 0:3b6c2ce051a6 12 #ifdef FEATURE_USBSERIAL
Helmut64 0:3b6c2ce051a6 13 USBSerialBuffered *usb;
Helmut64 0:3b6c2ce051a6 14 #endif
Helmut64 0:3b6c2ce051a6 15 bool _useDprintf;
Helmut64 0:3b6c2ce051a6 16
Helmut64 0:3b6c2ce051a6 17 void InitSerial(int timeout, DigitalOut *led)
Helmut64 0:3b6c2ce051a6 18 {
Helmut64 0:3b6c2ce051a6 19 _useDprintf = true;
Helmut64 0:3b6c2ce051a6 20 bool uartActive;
Helmut64 0:3b6c2ce051a6 21 {
Helmut64 0:3b6c2ce051a6 22 {
Helmut64 0:3b6c2ce051a6 23 // need to turn rx low to avoid floating signal
Helmut64 0:3b6c2ce051a6 24 DigitalOut rx(USBRX);
Helmut64 0:3b6c2ce051a6 25 rx = 0;
Helmut64 0:3b6c2ce051a6 26 }
Helmut64 0:3b6c2ce051a6 27 DigitalIn uartRX(USBRX);
Helmut64 0:3b6c2ce051a6 28 uartActive = uartRX.read();
Helmut64 0:3b6c2ce051a6 29 }
Helmut64 0:3b6c2ce051a6 30 #ifdef FEATURE_USBSERIAL
Helmut64 0:3b6c2ce051a6 31 if (!uartActive) {
Helmut64 0:3b6c2ce051a6 32 usb = new USBSerialBuffered();
Helmut64 0:3b6c2ce051a6 33 Timer t;
Helmut64 0:3b6c2ce051a6 34 t.start();
Helmut64 0:3b6c2ce051a6 35 while(!usb->connected()) {
Helmut64 0:3b6c2ce051a6 36 if (led)
Helmut64 0:3b6c2ce051a6 37 *led = !*led;
Helmut64 0:3b6c2ce051a6 38 wait_ms(100);
Helmut64 0:3b6c2ce051a6 39 if (timeout) {
Helmut Tschemernjak 5:c6a960febe80 40 if (t.read_ms() >= timeout) {
Helmut Tschemernjak 5:c6a960febe80 41 delete usb;
Helmut Tschemernjak 5:c6a960febe80 42 usb = NULL;
Helmut Tschemernjak 5:c6a960febe80 43 DigitalOut rx(USBRX);
Helmut Tschemernjak 5:c6a960febe80 44 rx = 0; // need to turn tx low to avoid floating signal
Helmut Tschemernjak 5:c6a960febe80 45 goto done;
Helmut Tschemernjak 5:c6a960febe80 46 }
Helmut64 0:3b6c2ce051a6 47 }
Helmut64 0:3b6c2ce051a6 48 }
Helmut Tschemernjak 5:c6a960febe80 49 goto done;
Helmut64 0:3b6c2ce051a6 50 } else {
Helmut64 0:3b6c2ce051a6 51 #else
Helmut64 0:3b6c2ce051a6 52 {
Helmut64 0:3b6c2ce051a6 53 #endif
Helmut64 0:3b6c2ce051a6 54 ser = new BufferedSerial(USBTX, USBRX);
Helmut64 0:3b6c2ce051a6 55 ser->baud(230400);
Helmut64 0:3b6c2ce051a6 56 ser->format(8);
Helmut64 0:3b6c2ce051a6 57 }
Helmut Tschemernjak 5:c6a960febe80 58 done:
Helmut64 0:3b6c2ce051a6 59 time_t t = cvt_date(__DATE__, __TIME__);
Helmut64 0:3b6c2ce051a6 60 if (t > time(NULL)) {
Helmut64 0:3b6c2ce051a6 61 set_time(t);
Helmut64 0:3b6c2ce051a6 62 }
Helmut64 0:3b6c2ce051a6 63 }
Helmut64 0:3b6c2ce051a6 64
Helmut64 0:3b6c2ce051a6 65 void printTimeStamp()
Helmut64 0:3b6c2ce051a6 66 {
Helmut64 0:3b6c2ce051a6 67 static LowPowerTimer *timer;
Helmut64 0:3b6c2ce051a6 68 if (!timer) {
Helmut64 0:3b6c2ce051a6 69 timer = new LowPowerTimer();
Helmut64 0:3b6c2ce051a6 70 timer->start();
Helmut64 0:3b6c2ce051a6 71 }
Helmut64 0:3b6c2ce051a6 72 time_t seconds = time(NULL);
Helmut64 0:3b6c2ce051a6 73 struct tm *tm = localtime(&seconds);
Helmut64 0:3b6c2ce051a6 74 int usecs = timer->read_us();
Helmut64 0:3b6c2ce051a6 75 if (usecs < 0) {
Helmut64 0:3b6c2ce051a6 76 usecs = 0;
Helmut64 0:3b6c2ce051a6 77 timer->stop();
Helmut64 0:3b6c2ce051a6 78 timer->reset();
Helmut64 0:3b6c2ce051a6 79 timer->start();
Helmut64 0:3b6c2ce051a6 80 }
Helmut64 0:3b6c2ce051a6 81 int msecs = usecs % 1000000;
Helmut64 0:3b6c2ce051a6 82
Helmut64 0:3b6c2ce051a6 83 rprintf("%02d:%02d:%02d.%06d ", tm->tm_hour, tm->tm_min, tm->tm_sec, msecs);
Helmut64 0:3b6c2ce051a6 84 }
Helmut64 0:3b6c2ce051a6 85
Helmut64 0:3b6c2ce051a6 86 void dprintf(const char *format, ...)
Helmut64 0:3b6c2ce051a6 87 {
Helmut64 0:3b6c2ce051a6 88 std::va_list arg;
Helmut64 0:3b6c2ce051a6 89
Helmut64 0:3b6c2ce051a6 90 va_start(arg, format);
Helmut64 0:3b6c2ce051a6 91 VAprintf(true, true, _useDprintf, format, arg);
Helmut64 0:3b6c2ce051a6 92 va_end(arg);
Helmut64 0:3b6c2ce051a6 93 }
Helmut64 0:3b6c2ce051a6 94
Helmut64 0:3b6c2ce051a6 95 void rprintf(const char *format, ...)
Helmut64 0:3b6c2ce051a6 96 {
Helmut64 0:3b6c2ce051a6 97 std::va_list arg;
Helmut64 0:3b6c2ce051a6 98
Helmut64 0:3b6c2ce051a6 99 va_start(arg, format);
Helmut64 0:3b6c2ce051a6 100 VAprintf(false, false, _useDprintf, format, arg);
Helmut64 0:3b6c2ce051a6 101 va_end(arg);
Helmut64 0:3b6c2ce051a6 102 }
Helmut64 0:3b6c2ce051a6 103
Helmut64 0:3b6c2ce051a6 104 void VAprintf(bool timstamp, bool newline, bool printEnabled, const char *format, va_list arg)
Helmut64 0:3b6c2ce051a6 105 {
Helmut64 0:3b6c2ce051a6 106 if (!printEnabled)
Helmut64 0:3b6c2ce051a6 107 return;
Helmut64 0:3b6c2ce051a6 108
Helmut64 0:3b6c2ce051a6 109 if (timstamp)
Helmut64 0:3b6c2ce051a6 110 printTimeStamp();
Helmut64 0:3b6c2ce051a6 111 #ifdef FEATURE_USBSERIAL
Helmut64 0:3b6c2ce051a6 112 if (usb) {
Helmut64 0:3b6c2ce051a6 113 usb->vprintf_irqsafe(format, arg);
Helmut64 0:3b6c2ce051a6 114 if (newline)
Helmut64 0:3b6c2ce051a6 115 usb->printf_irqsafe("\r\n");
Helmut64 0:3b6c2ce051a6 116 #else
Helmut64 0:3b6c2ce051a6 117 if (0) {
Helmut64 0:3b6c2ce051a6 118 #endif
Helmut64 0:3b6c2ce051a6 119 } else if (ser) {
Helmut64 0:3b6c2ce051a6 120 // serial jas
Helmut64 0:3b6c2ce051a6 121 int r = 0;
Helmut64 0:3b6c2ce051a6 122 r = vsnprintf(NULL, 0, format, arg);
Helmut64 0:3b6c2ce051a6 123 if (r < 82) {
Helmut64 0:3b6c2ce051a6 124 char buffer[82+1];
Helmut64 0:3b6c2ce051a6 125
Helmut64 0:3b6c2ce051a6 126 vsnprintf(buffer, sizeof(buffer), format, arg);
Helmut64 0:3b6c2ce051a6 127 r = ser->write(buffer, r);
Helmut64 0:3b6c2ce051a6 128 } else {
Helmut64 0:3b6c2ce051a6 129 char *buffer = new char[r+1];
Helmut64 0:3b6c2ce051a6 130 if (buffer) {
Helmut64 0:3b6c2ce051a6 131 vsnprintf(buffer, r+1, format, arg);
Helmut64 0:3b6c2ce051a6 132 r = ser->write(buffer, r);
Helmut64 0:3b6c2ce051a6 133 delete[] buffer;
Helmut64 0:3b6c2ce051a6 134 } else {
Helmut64 0:3b6c2ce051a6 135 error("%s %d cannot alloc memory (%d bytes)!\r\n", __FILE__, __LINE__, r+1);
Helmut64 0:3b6c2ce051a6 136 r = 0;
Helmut64 0:3b6c2ce051a6 137 }
Helmut64 0:3b6c2ce051a6 138 }
Helmut64 0:3b6c2ce051a6 139 if (newline)
Helmut64 0:3b6c2ce051a6 140 ser->write("\r\n", 2);
Helmut64 0:3b6c2ce051a6 141 }
Helmut64 0:3b6c2ce051a6 142 }
Helmut64 0:3b6c2ce051a6 143
Helmut Tschemernjak 14:d9340be18c3d 144 char *ConsoleReadline(char *buf, int buflen, bool echo)
Helmut Tschemernjak 14:d9340be18c3d 145 {
Helmut Tschemernjak 14:d9340be18c3d 146 int count = 0;
Helmut Tschemernjak 14:d9340be18c3d 147 memset(buf, 0, buflen);
Helmut Tschemernjak 14:d9340be18c3d 148
Helmut Tschemernjak 14:d9340be18c3d 149 if (usb ) {
Helmut Tschemernjak 14:d9340be18c3d 150 usb->flush();
Helmut Tschemernjak 14:d9340be18c3d 151 while(usb->readable())
Helmut Tschemernjak 14:d9340be18c3d 152 usb->getc(); // flush old chars
Helmut Tschemernjak 14:d9340be18c3d 153
Helmut Tschemernjak 14:d9340be18c3d 154 while(true) {
Helmut Tschemernjak 14:d9340be18c3d 155 if (usb->readable()) {
Helmut Tschemernjak 14:d9340be18c3d 156 int c = usb->getc();
Helmut Tschemernjak 14:d9340be18c3d 157 if (c == 0 || c == -1 || c == '\r' || c == '\n' || c == 3 || c == 4)
Helmut Tschemernjak 14:d9340be18c3d 158 break;
Helmut Tschemernjak 14:d9340be18c3d 159 if (echo) {
Helmut Tschemernjak 14:d9340be18c3d 160 rprintf("%c", c);
Helmut Tschemernjak 14:d9340be18c3d 161 usb->flush();
Helmut Tschemernjak 14:d9340be18c3d 162 }
Helmut Tschemernjak 14:d9340be18c3d 163
Helmut Tschemernjak 14:d9340be18c3d 164 buf[count] = c;
Helmut Tschemernjak 14:d9340be18c3d 165 if (count++ >= buflen-2)
Helmut Tschemernjak 14:d9340be18c3d 166 break;
Helmut Tschemernjak 14:d9340be18c3d 167 // dprintf("Got char: '%c'(%d)", c, c);
Helmut Tschemernjak 14:d9340be18c3d 168 }
Helmut Tschemernjak 14:d9340be18c3d 169 }
Helmut Tschemernjak 14:d9340be18c3d 170 }
Helmut Tschemernjak 14:d9340be18c3d 171 if (ser) {
Helmut Tschemernjak 14:d9340be18c3d 172 while(ser->readable())
Helmut Tschemernjak 14:d9340be18c3d 173 ser->getc(); // flush old chars
Helmut Tschemernjak 14:d9340be18c3d 174
Helmut Tschemernjak 14:d9340be18c3d 175 while(true) {
Helmut Tschemernjak 14:d9340be18c3d 176 if (ser->readable()) {
Helmut Tschemernjak 14:d9340be18c3d 177 int c = ser->getc();
Helmut Tschemernjak 14:d9340be18c3d 178 if (c == 0 || c == -1 || c == '\r' || c == '\n' || c == 3 || c == 4)
Helmut Tschemernjak 14:d9340be18c3d 179 break;
Helmut Tschemernjak 14:d9340be18c3d 180 if (echo)
Helmut Tschemernjak 14:d9340be18c3d 181 rprintf("%c", c);
Helmut Tschemernjak 14:d9340be18c3d 182 buf[count] = c;
Helmut Tschemernjak 14:d9340be18c3d 183 if (count++ >= buflen-2)
Helmut Tschemernjak 14:d9340be18c3d 184 break;
Helmut Tschemernjak 14:d9340be18c3d 185 // dprintf("Got char: '%c'(%d)", c, c);
Helmut Tschemernjak 14:d9340be18c3d 186 }
Helmut Tschemernjak 14:d9340be18c3d 187 }
Helmut Tschemernjak 14:d9340be18c3d 188 }
Helmut Tschemernjak 14:d9340be18c3d 189 if (echo)
Helmut Tschemernjak 14:d9340be18c3d 190 rprintf("\r\n");
Helmut Tschemernjak 14:d9340be18c3d 191 if (count)
Helmut Tschemernjak 14:d9340be18c3d 192 return buf;
Helmut Tschemernjak 14:d9340be18c3d 193 return NULL;
Helmut Tschemernjak 14:d9340be18c3d 194 }
Helmut Tschemernjak 14:d9340be18c3d 195
Helmut64 0:3b6c2ce051a6 196
Helmut64 0:3b6c2ce051a6 197 void dump(const char *title, const void *data, int len, bool dwords)
Helmut64 0:3b6c2ce051a6 198 {
Helmut Tschemernjak 14:d9340be18c3d 199 dprintf("dump(\"%s\", 0x%x, %d bytes)", title, (unsigned int)data, len);
Helmut64 0:3b6c2ce051a6 200
Helmut64 0:3b6c2ce051a6 201 int i, j, cnt;
Helmut64 0:3b6c2ce051a6 202 unsigned char *u;
Helmut64 0:3b6c2ce051a6 203 const int width = 16;
Helmut64 0:3b6c2ce051a6 204 const int seppos = 7;
Helmut64 0:3b6c2ce051a6 205
Helmut64 0:3b6c2ce051a6 206 cnt = 0;
Helmut64 0:3b6c2ce051a6 207 u = (unsigned char *)data;
Helmut64 0:3b6c2ce051a6 208 while (len > 0) {
Helmut64 0:3b6c2ce051a6 209 rprintf("%08x: ", (unsigned int)data + cnt);
Helmut64 0:3b6c2ce051a6 210 if (dwords) {
Helmut64 0:3b6c2ce051a6 211 unsigned int *ip = ( unsigned int *)u;
Helmut64 0:3b6c2ce051a6 212 rprintf(" 0x%08x\r\n", *ip);
Helmut64 0:3b6c2ce051a6 213 u+= 4;
Helmut64 0:3b6c2ce051a6 214 len -= 4;
Helmut64 0:3b6c2ce051a6 215 cnt += 4;
Helmut64 0:3b6c2ce051a6 216 continue;
Helmut64 0:3b6c2ce051a6 217 }
Helmut64 0:3b6c2ce051a6 218 cnt += width;
Helmut64 0:3b6c2ce051a6 219 j = len < width ? len : width;
Helmut64 0:3b6c2ce051a6 220 for (i = 0; i < j; i++) {
Helmut64 0:3b6c2ce051a6 221 rprintf("%2.2x ", *(u + i));
Helmut64 0:3b6c2ce051a6 222 if (i == seppos)
Helmut64 0:3b6c2ce051a6 223 rprintf(" ");
Helmut64 0:3b6c2ce051a6 224 }
Helmut64 0:3b6c2ce051a6 225 rprintf(" ");
Helmut64 0:3b6c2ce051a6 226 if (j < width) {
Helmut64 0:3b6c2ce051a6 227 i = width - j;
Helmut64 0:3b6c2ce051a6 228 if (i > seppos + 1)
Helmut64 0:3b6c2ce051a6 229 rprintf(" ");
Helmut64 0:3b6c2ce051a6 230 while (i--) {
Helmut64 0:3b6c2ce051a6 231 rprintf("%s", " ");
Helmut64 0:3b6c2ce051a6 232 }
Helmut64 0:3b6c2ce051a6 233 }
Helmut64 0:3b6c2ce051a6 234 for (i = 0; i < j; i++) {
Helmut64 0:3b6c2ce051a6 235 int c = *(u + i);
Helmut64 0:3b6c2ce051a6 236 if (c >= ' ' && c <= '~')
Helmut64 0:3b6c2ce051a6 237 rprintf("%c", c);
Helmut64 0:3b6c2ce051a6 238 else
Helmut64 0:3b6c2ce051a6 239 rprintf(".");
Helmut64 0:3b6c2ce051a6 240 if (i == seppos)
Helmut64 0:3b6c2ce051a6 241 rprintf(" ");
Helmut64 0:3b6c2ce051a6 242 }
Helmut64 0:3b6c2ce051a6 243 len -= width;
Helmut64 0:3b6c2ce051a6 244 u += width;
Helmut64 0:3b6c2ce051a6 245 rprintf("\r\n");
Helmut64 0:3b6c2ce051a6 246 }
Helmut64 0:3b6c2ce051a6 247 rprintf("--\r\n");
Helmut64 0:3b6c2ce051a6 248 }
Helmut64 0:3b6c2ce051a6 249
Helmut64 0:3b6c2ce051a6 250 /*
Helmut64 0:3b6c2ce051a6 251 * Convert compile time to system time
Helmut64 0:3b6c2ce051a6 252 */
Helmut64 0:3b6c2ce051a6 253 time_t
Helmut64 0:3b6c2ce051a6 254 cvt_date(char const *date, char const *time)
Helmut64 0:3b6c2ce051a6 255 {
Helmut64 0:3b6c2ce051a6 256 char s_month[5];
Helmut64 0:3b6c2ce051a6 257 int year;
Helmut64 0:3b6c2ce051a6 258 struct tm t;
Helmut64 0:3b6c2ce051a6 259 static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
Helmut64 0:3b6c2ce051a6 260 sscanf(date, "%s %d %d", s_month, &t.tm_mday, &year);
Helmut64 0:3b6c2ce051a6 261 sscanf(time, "%2d %*c %2d %*c %2d", &t.tm_hour, &t.tm_min, &t.tm_sec);
Helmut64 0:3b6c2ce051a6 262 // Find where is s_month in month_names. Deduce month value.
Helmut64 0:3b6c2ce051a6 263 t.tm_mon = (strstr(month_names, s_month) - month_names) / 3;
Helmut64 0:3b6c2ce051a6 264 t.tm_year = year - 1900;
Helmut64 0:3b6c2ce051a6 265 return (int)mktime(&t);
Helmut64 0:3b6c2ce051a6 266 }
Helmut Tschemernjak 1:56fdc660a26a 267
Helmut Tschemernjak 1:56fdc660a26a 268
Helmut Tschemernjak 1:56fdc660a26a 269
Helmut Tschemernjak 1:56fdc660a26a 270 void InterrruptMSG(enum InterrruptDevice irqid) {
Helmut Tschemernjak 1:56fdc660a26a 271 help_atomic_or_relaxed(&PendingInterrupts, irqid);
Helmut Tschemernjak 1:56fdc660a26a 272 }
Helmut Tschemernjak 1:56fdc660a26a 273
Helmut Tschemernjak 1:56fdc660a26a 274
Helmut Tschemernjak 1:56fdc660a26a 275 uint32_t readclrPendingInterrupts() {
Helmut Tschemernjak 1:56fdc660a26a 276 return help_atomic_readclr_relaxed(&PendingInterrupts);
Helmut Tschemernjak 1:56fdc660a26a 277 }
Helmut Tschemernjak 1:56fdc660a26a 278
Helmut Tschemernjak 1:56fdc660a26a 279 uint32_t readPendingInterrupts() {
Helmut Tschemernjak 1:56fdc660a26a 280 return help_atomic_load_relaxed(&PendingInterrupts);
Helmut Tschemernjak 1:56fdc660a26a 281 }
Helmut Tschemernjak 1:56fdc660a26a 282
Helmut Tschemernjak 1:56fdc660a26a 283 const char *
Helmut Tschemernjak 1:56fdc660a26a 284 BatterySource(void)
Helmut Tschemernjak 1:56fdc660a26a 285 {
Helmut Tschemernjak 1:56fdc660a26a 286 const char *pwrSource = "Battery";
Helmut Tschemernjak 1:56fdc660a26a 287 #ifdef BATPOWER_EN
Helmut Tschemernjak 1:56fdc660a26a 288 {
Helmut Tschemernjak 1:56fdc660a26a 289 DigitalIn pwr(BATPOWER_EN);
Helmut Tschemernjak 1:56fdc660a26a 290 if (pwr == BATPOWER_EXT)
Helmut Tschemernjak 1:56fdc660a26a 291 pwrSource = "USB";
Helmut Tschemernjak 1:56fdc660a26a 292 }
Helmut Tschemernjak 1:56fdc660a26a 293 #endif
Helmut Tschemernjak 1:56fdc660a26a 294 return pwrSource;
Helmut Tschemernjak 1:56fdc660a26a 295 }
Helmut Tschemernjak 1:56fdc660a26a 296