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:
Helmut64
Date:
Fri Jan 18 15:59:46 2019 +0000
Revision:
0:3b6c2ce051a6
Child:
1:56fdc660a26a
inital checkin

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Helmut64 0:3b6c2ce051a6 1 /*
Helmut64 0:3b6c2ce051a6 2 * Copyright (c) 2018 Helmut Tschemernjak
Helmut64 0:3b6c2ce051a6 3 * 30826 Garbsen (Hannover) Germany
Helmut64 0:3b6c2ce051a6 4 */
Helmut64 0:3b6c2ce051a6 5 #include "main.h"
Helmut64 0:3b6c2ce051a6 6
Helmut64 0:3b6c2ce051a6 7 time_t cvt_date(char const *date, char const *time);
Helmut64 0:3b6c2ce051a6 8
Helmut64 0:3b6c2ce051a6 9 BufferedSerial *ser;
Helmut64 0:3b6c2ce051a6 10 #ifdef FEATURE_USBSERIAL
Helmut64 0:3b6c2ce051a6 11 USBSerialBuffered *usb;
Helmut64 0:3b6c2ce051a6 12 #endif
Helmut64 0:3b6c2ce051a6 13 bool _useDprintf;
Helmut64 0:3b6c2ce051a6 14
Helmut64 0:3b6c2ce051a6 15 void InitSerial(int timeout, DigitalOut *led)
Helmut64 0:3b6c2ce051a6 16 {
Helmut64 0:3b6c2ce051a6 17 _useDprintf = true;
Helmut64 0:3b6c2ce051a6 18 bool uartActive;
Helmut64 0:3b6c2ce051a6 19 {
Helmut64 0:3b6c2ce051a6 20 {
Helmut64 0:3b6c2ce051a6 21 // need to turn rx low to avoid floating signal
Helmut64 0:3b6c2ce051a6 22 DigitalOut rx(USBRX);
Helmut64 0:3b6c2ce051a6 23 rx = 0;
Helmut64 0:3b6c2ce051a6 24 }
Helmut64 0:3b6c2ce051a6 25 DigitalIn uartRX(USBRX);
Helmut64 0:3b6c2ce051a6 26 uartActive = uartRX.read();
Helmut64 0:3b6c2ce051a6 27 }
Helmut64 0:3b6c2ce051a6 28 #ifdef FEATURE_USBSERIAL
Helmut64 0:3b6c2ce051a6 29 if (!uartActive) {
Helmut64 0:3b6c2ce051a6 30 usb = new USBSerialBuffered();
Helmut64 0:3b6c2ce051a6 31 Timer t;
Helmut64 0:3b6c2ce051a6 32 t.start();
Helmut64 0:3b6c2ce051a6 33 while(!usb->connected()) {
Helmut64 0:3b6c2ce051a6 34 if (led)
Helmut64 0:3b6c2ce051a6 35 *led = !*led;
Helmut64 0:3b6c2ce051a6 36 wait_ms(100);
Helmut64 0:3b6c2ce051a6 37 if (timeout) {
Helmut64 0:3b6c2ce051a6 38 if (t.read_ms() >= timeout)
Helmut64 0:3b6c2ce051a6 39 return;
Helmut64 0:3b6c2ce051a6 40 }
Helmut64 0:3b6c2ce051a6 41 }
Helmut64 0:3b6c2ce051a6 42 return;
Helmut64 0:3b6c2ce051a6 43 } else {
Helmut64 0:3b6c2ce051a6 44 #else
Helmut64 0:3b6c2ce051a6 45 {
Helmut64 0:3b6c2ce051a6 46 #endif
Helmut64 0:3b6c2ce051a6 47 ser = new BufferedSerial(USBTX, USBRX);
Helmut64 0:3b6c2ce051a6 48 ser->baud(230400);
Helmut64 0:3b6c2ce051a6 49 ser->format(8);
Helmut64 0:3b6c2ce051a6 50 }
Helmut64 0:3b6c2ce051a6 51 time_t t = cvt_date(__DATE__, __TIME__);
Helmut64 0:3b6c2ce051a6 52 if (t > time(NULL)) {
Helmut64 0:3b6c2ce051a6 53 set_time(t);
Helmut64 0:3b6c2ce051a6 54 }
Helmut64 0:3b6c2ce051a6 55
Helmut64 0:3b6c2ce051a6 56 }
Helmut64 0:3b6c2ce051a6 57
Helmut64 0:3b6c2ce051a6 58 void printTimeStamp()
Helmut64 0:3b6c2ce051a6 59 {
Helmut64 0:3b6c2ce051a6 60 static LowPowerTimer *timer;
Helmut64 0:3b6c2ce051a6 61 if (!timer) {
Helmut64 0:3b6c2ce051a6 62 timer = new LowPowerTimer();
Helmut64 0:3b6c2ce051a6 63 timer->start();
Helmut64 0:3b6c2ce051a6 64 }
Helmut64 0:3b6c2ce051a6 65 time_t seconds = time(NULL);
Helmut64 0:3b6c2ce051a6 66 struct tm *tm = localtime(&seconds);
Helmut64 0:3b6c2ce051a6 67 int usecs = timer->read_us();
Helmut64 0:3b6c2ce051a6 68 if (usecs < 0) {
Helmut64 0:3b6c2ce051a6 69 usecs = 0;
Helmut64 0:3b6c2ce051a6 70 timer->stop();
Helmut64 0:3b6c2ce051a6 71 timer->reset();
Helmut64 0:3b6c2ce051a6 72 timer->start();
Helmut64 0:3b6c2ce051a6 73 }
Helmut64 0:3b6c2ce051a6 74 int msecs = usecs % 1000000;
Helmut64 0:3b6c2ce051a6 75
Helmut64 0:3b6c2ce051a6 76 rprintf("%02d:%02d:%02d.%06d ", tm->tm_hour, tm->tm_min, tm->tm_sec, msecs);
Helmut64 0:3b6c2ce051a6 77 }
Helmut64 0:3b6c2ce051a6 78
Helmut64 0:3b6c2ce051a6 79 void dprintf(const char *format, ...)
Helmut64 0:3b6c2ce051a6 80 {
Helmut64 0:3b6c2ce051a6 81 std::va_list arg;
Helmut64 0:3b6c2ce051a6 82
Helmut64 0:3b6c2ce051a6 83 va_start(arg, format);
Helmut64 0:3b6c2ce051a6 84 VAprintf(true, true, _useDprintf, format, arg);
Helmut64 0:3b6c2ce051a6 85 va_end(arg);
Helmut64 0:3b6c2ce051a6 86 }
Helmut64 0:3b6c2ce051a6 87
Helmut64 0:3b6c2ce051a6 88 void rprintf(const char *format, ...)
Helmut64 0:3b6c2ce051a6 89 {
Helmut64 0:3b6c2ce051a6 90 std::va_list arg;
Helmut64 0:3b6c2ce051a6 91
Helmut64 0:3b6c2ce051a6 92 va_start(arg, format);
Helmut64 0:3b6c2ce051a6 93 VAprintf(false, false, _useDprintf, format, arg);
Helmut64 0:3b6c2ce051a6 94 va_end(arg);
Helmut64 0:3b6c2ce051a6 95 }
Helmut64 0:3b6c2ce051a6 96
Helmut64 0:3b6c2ce051a6 97 void VAprintf(bool timstamp, bool newline, bool printEnabled, const char *format, va_list arg)
Helmut64 0:3b6c2ce051a6 98 {
Helmut64 0:3b6c2ce051a6 99 if (!printEnabled)
Helmut64 0:3b6c2ce051a6 100 return;
Helmut64 0:3b6c2ce051a6 101
Helmut64 0:3b6c2ce051a6 102 if (timstamp)
Helmut64 0:3b6c2ce051a6 103 printTimeStamp();
Helmut64 0:3b6c2ce051a6 104 #ifdef FEATURE_USBSERIAL
Helmut64 0:3b6c2ce051a6 105 if (usb) {
Helmut64 0:3b6c2ce051a6 106 usb->vprintf_irqsafe(format, arg);
Helmut64 0:3b6c2ce051a6 107 if (newline)
Helmut64 0:3b6c2ce051a6 108 usb->printf_irqsafe("\r\n");
Helmut64 0:3b6c2ce051a6 109 #else
Helmut64 0:3b6c2ce051a6 110 if (0) {
Helmut64 0:3b6c2ce051a6 111 #endif
Helmut64 0:3b6c2ce051a6 112 } else if (ser) {
Helmut64 0:3b6c2ce051a6 113 // serial jas
Helmut64 0:3b6c2ce051a6 114 int r = 0;
Helmut64 0:3b6c2ce051a6 115 r = vsnprintf(NULL, 0, format, arg);
Helmut64 0:3b6c2ce051a6 116 if (r < 82) {
Helmut64 0:3b6c2ce051a6 117 char buffer[82+1];
Helmut64 0:3b6c2ce051a6 118
Helmut64 0:3b6c2ce051a6 119 vsnprintf(buffer, sizeof(buffer), format, arg);
Helmut64 0:3b6c2ce051a6 120 r = ser->write(buffer, r);
Helmut64 0:3b6c2ce051a6 121 } else {
Helmut64 0:3b6c2ce051a6 122 char *buffer = new char[r+1];
Helmut64 0:3b6c2ce051a6 123 if (buffer) {
Helmut64 0:3b6c2ce051a6 124 vsnprintf(buffer, r+1, format, arg);
Helmut64 0:3b6c2ce051a6 125 r = ser->write(buffer, r);
Helmut64 0:3b6c2ce051a6 126 delete[] buffer;
Helmut64 0:3b6c2ce051a6 127 } else {
Helmut64 0:3b6c2ce051a6 128 error("%s %d cannot alloc memory (%d bytes)!\r\n", __FILE__, __LINE__, r+1);
Helmut64 0:3b6c2ce051a6 129 r = 0;
Helmut64 0:3b6c2ce051a6 130 }
Helmut64 0:3b6c2ce051a6 131 }
Helmut64 0:3b6c2ce051a6 132 if (newline)
Helmut64 0:3b6c2ce051a6 133 ser->write("\r\n", 2);
Helmut64 0:3b6c2ce051a6 134 }
Helmut64 0:3b6c2ce051a6 135 }
Helmut64 0:3b6c2ce051a6 136
Helmut64 0:3b6c2ce051a6 137
Helmut64 0:3b6c2ce051a6 138 void dump(const char *title, const void *data, int len, bool dwords)
Helmut64 0:3b6c2ce051a6 139 {
Helmut64 0:3b6c2ce051a6 140 dprintf("dump(\"%s\", 0x%x, %d bytes)", title, data, len);
Helmut64 0:3b6c2ce051a6 141
Helmut64 0:3b6c2ce051a6 142 int i, j, cnt;
Helmut64 0:3b6c2ce051a6 143 unsigned char *u;
Helmut64 0:3b6c2ce051a6 144 const int width = 16;
Helmut64 0:3b6c2ce051a6 145 const int seppos = 7;
Helmut64 0:3b6c2ce051a6 146
Helmut64 0:3b6c2ce051a6 147 cnt = 0;
Helmut64 0:3b6c2ce051a6 148 u = (unsigned char *)data;
Helmut64 0:3b6c2ce051a6 149 while (len > 0) {
Helmut64 0:3b6c2ce051a6 150 rprintf("%08x: ", (unsigned int)data + cnt);
Helmut64 0:3b6c2ce051a6 151 if (dwords) {
Helmut64 0:3b6c2ce051a6 152 unsigned int *ip = ( unsigned int *)u;
Helmut64 0:3b6c2ce051a6 153 rprintf(" 0x%08x\r\n", *ip);
Helmut64 0:3b6c2ce051a6 154 u+= 4;
Helmut64 0:3b6c2ce051a6 155 len -= 4;
Helmut64 0:3b6c2ce051a6 156 cnt += 4;
Helmut64 0:3b6c2ce051a6 157 continue;
Helmut64 0:3b6c2ce051a6 158 }
Helmut64 0:3b6c2ce051a6 159 cnt += width;
Helmut64 0:3b6c2ce051a6 160 j = len < width ? len : width;
Helmut64 0:3b6c2ce051a6 161 for (i = 0; i < j; i++) {
Helmut64 0:3b6c2ce051a6 162 rprintf("%2.2x ", *(u + i));
Helmut64 0:3b6c2ce051a6 163 if (i == seppos)
Helmut64 0:3b6c2ce051a6 164 rprintf(" ");
Helmut64 0:3b6c2ce051a6 165 }
Helmut64 0:3b6c2ce051a6 166 rprintf(" ");
Helmut64 0:3b6c2ce051a6 167 if (j < width) {
Helmut64 0:3b6c2ce051a6 168 i = width - j;
Helmut64 0:3b6c2ce051a6 169 if (i > seppos + 1)
Helmut64 0:3b6c2ce051a6 170 rprintf(" ");
Helmut64 0:3b6c2ce051a6 171 while (i--) {
Helmut64 0:3b6c2ce051a6 172 rprintf("%s", " ");
Helmut64 0:3b6c2ce051a6 173 }
Helmut64 0:3b6c2ce051a6 174 }
Helmut64 0:3b6c2ce051a6 175 for (i = 0; i < j; i++) {
Helmut64 0:3b6c2ce051a6 176 int c = *(u + i);
Helmut64 0:3b6c2ce051a6 177 if (c >= ' ' && c <= '~')
Helmut64 0:3b6c2ce051a6 178 rprintf("%c", c);
Helmut64 0:3b6c2ce051a6 179 else
Helmut64 0:3b6c2ce051a6 180 rprintf(".");
Helmut64 0:3b6c2ce051a6 181 if (i == seppos)
Helmut64 0:3b6c2ce051a6 182 rprintf(" ");
Helmut64 0:3b6c2ce051a6 183 }
Helmut64 0:3b6c2ce051a6 184 len -= width;
Helmut64 0:3b6c2ce051a6 185 u += width;
Helmut64 0:3b6c2ce051a6 186 rprintf("\r\n");
Helmut64 0:3b6c2ce051a6 187 }
Helmut64 0:3b6c2ce051a6 188 rprintf("--\r\n");
Helmut64 0:3b6c2ce051a6 189 }
Helmut64 0:3b6c2ce051a6 190
Helmut64 0:3b6c2ce051a6 191 /*
Helmut64 0:3b6c2ce051a6 192 * Convert compile time to system time
Helmut64 0:3b6c2ce051a6 193 */
Helmut64 0:3b6c2ce051a6 194 time_t
Helmut64 0:3b6c2ce051a6 195 cvt_date(char const *date, char const *time)
Helmut64 0:3b6c2ce051a6 196 {
Helmut64 0:3b6c2ce051a6 197 char s_month[5];
Helmut64 0:3b6c2ce051a6 198 int year;
Helmut64 0:3b6c2ce051a6 199 struct tm t;
Helmut64 0:3b6c2ce051a6 200 static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
Helmut64 0:3b6c2ce051a6 201 sscanf(date, "%s %d %d", s_month, &t.tm_mday, &year);
Helmut64 0:3b6c2ce051a6 202 sscanf(time, "%2d %*c %2d %*c %2d", &t.tm_hour, &t.tm_min, &t.tm_sec);
Helmut64 0:3b6c2ce051a6 203 // Find where is s_month in month_names. Deduce month value.
Helmut64 0:3b6c2ce051a6 204 t.tm_mon = (strstr(month_names, s_month) - month_names) / 3;
Helmut64 0:3b6c2ce051a6 205 t.tm_year = year - 1900;
Helmut64 0:3b6c2ce051a6 206 return (int)mktime(&t);
Helmut64 0:3b6c2ce051a6 207 }