test sending sensor results over lora radio. Accelerometer and temp/pressure.

Dependencies:   SX127x

Serial terminal operates at 115200.

This project provides a text-based menu over serial port.
Operating the program only requires using the arrow keys, enter key to activate a control, or entering numbers.

Two sensors provided:


LIS12DH12 accelerometer operates in a continuous sampling mode. Enable control for accelerometer enables this continuous sampling, approx every 3 seconds.
LPS22HH temperature / pressure sensor operates as single shot, where pressing the control button on terminal causes single sample to be performed.

poll rate control will enable repeated reading of pressure/temperature-sensor or photo-sensor when poll rate is greater than zero.

target must be: DISCO_L072CZ_LRWAN1

Committer:
Wayne Roberts
Date:
Wed Apr 24 10:11:06 2019 -0700
Revision:
0:e1e70da93044
Child:
2:972a5704f152
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:e1e70da93044 1 #include "mbed.h"
Wayne Roberts 0:e1e70da93044 2 #include "radio.h"
Wayne Roberts 0:e1e70da93044 3 #include "demo.h"
Wayne Roberts 0:e1e70da93044 4
Wayne Roberts 0:e1e70da93044 5 bool svc_lis2dh12;
Wayne Roberts 0:e1e70da93044 6 //#define MENU_DEBUG
Wayne Roberts 0:e1e70da93044 7
Wayne Roberts 0:e1e70da93044 8 RawSerial pc(USBTX, USBRX);
Wayne Roberts 0:e1e70da93044 9
Wayne Roberts 0:e1e70da93044 10 menuState_t menuState;
Wayne Roberts 0:e1e70da93044 11
Wayne Roberts 0:e1e70da93044 12 typedef enum {
Wayne Roberts 0:e1e70da93044 13 MSG_TYPE_PACKET = 0,
Wayne Roberts 0:e1e70da93044 14 MSG_TYPE_PER,
Wayne Roberts 0:e1e70da93044 15 MSG_TYPE_PINGPONG
Wayne Roberts 0:e1e70da93044 16 } msgType_e;
Wayne Roberts 0:e1e70da93044 17
Wayne Roberts 0:e1e70da93044 18 enum {
Wayne Roberts 0:e1e70da93044 19 CMD_TEMP,
Wayne Roberts 0:e1e70da93044 20 CMD_PRES,
Wayne Roberts 0:e1e70da93044 21 CMD_ACCEL,
Wayne Roberts 0:e1e70da93044 22 CMD_PHOTOS
Wayne Roberts 0:e1e70da93044 23 };
Wayne Roberts 0:e1e70da93044 24
Wayne Roberts 0:e1e70da93044 25 #define MAX_MENU_ROWS 16
Wayne Roberts 0:e1e70da93044 26 // [row][column]
Wayne Roberts 0:e1e70da93044 27 const menu_t* menu_table[MAX_MENU_ROWS][MAX_MENU_COLUMNS];
Wayne Roberts 0:e1e70da93044 28 int8_t StopMenuCols[MAX_MENU_ROWS];
Wayne Roberts 0:e1e70da93044 29
Wayne Roberts 0:e1e70da93044 30 //#define SCROLLING_ROWS 20
Wayne Roberts 0:e1e70da93044 31 #define SCROLLING_ROWS 30
Wayne Roberts 0:e1e70da93044 32
Wayne Roberts 0:e1e70da93044 33 struct _cp_ {
Wayne Roberts 0:e1e70da93044 34 uint8_t row;
Wayne Roberts 0:e1e70da93044 35 uint8_t tableCol;
Wayne Roberts 0:e1e70da93044 36 } curpos;
Wayne Roberts 0:e1e70da93044 37
Wayne Roberts 0:e1e70da93044 38 uint8_t entry_buf_idx;
Wayne Roberts 0:e1e70da93044 39 char entry_buf[64];
Wayne Roberts 0:e1e70da93044 40
Wayne Roberts 0:e1e70da93044 41 msgType_e msg_type;
Wayne Roberts 0:e1e70da93044 42
Wayne Roberts 0:e1e70da93044 43 const uint8_t PingMsg[] = "PING";
Wayne Roberts 0:e1e70da93044 44 const uint8_t PongMsg[] = "PONG";
Wayne Roberts 0:e1e70da93044 45 const uint8_t PerMsg[] = "PER";
Wayne Roberts 0:e1e70da93044 46
Wayne Roberts 0:e1e70da93044 47 volatile struct _flags_ {
Wayne Roberts 0:e1e70da93044 48 uint8_t ping_master : 1; // 0
Wayne Roberts 0:e1e70da93044 49 uint8_t send_ping : 1; // 1
Wayne Roberts 0:e1e70da93044 50 uint8_t send_pong : 1; // 2
Wayne Roberts 0:e1e70da93044 51 uint8_t pingpongEnable : 1; // 3
Wayne Roberts 0:e1e70da93044 52 uint8_t do_next_tx : 1; // 4
Wayne Roberts 0:e1e70da93044 53 } flags;
Wayne Roberts 0:e1e70da93044 54
Wayne Roberts 0:e1e70da93044 55 uint8_t botRow;
Wayne Roberts 0:e1e70da93044 56 int regAddr = -1;
Wayne Roberts 0:e1e70da93044 57
Wayne Roberts 0:e1e70da93044 58 /*
Wayne Roberts 0:e1e70da93044 59 * available pins PA_0, PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7, PB_0, PB_1, PC_0, PC_1, PC_2
Wayne Roberts 0:e1e70da93044 60 #define PHOTOS_PIN
Wayne Roberts 0:e1e70da93044 61 */
Wayne Roberts 0:e1e70da93044 62 #ifdef PHOTOS_PIN
Wayne Roberts 0:e1e70da93044 63 AnalogIn photos(PHOTOS_PIN);
Wayne Roberts 0:e1e70da93044 64 #endif /* PHOTOS_PIN */
Wayne Roberts 0:e1e70da93044 65
Wayne Roberts 0:e1e70da93044 66 #define UART_RX_BUF_LEN 8
Wayne Roberts 0:e1e70da93044 67 uint8_t uart_rx_buf[UART_RX_BUF_LEN];
Wayne Roberts 0:e1e70da93044 68 volatile uint8_t uart_rx_buf_in;
Wayne Roberts 0:e1e70da93044 69 volatile uint8_t uart_rx_buf_out;
Wayne Roberts 0:e1e70da93044 70 bool accel_tx_en;
Wayne Roberts 0:e1e70da93044 71
Wayne Roberts 0:e1e70da93044 72 #ifdef MENU_DEBUG
Wayne Roberts 0:e1e70da93044 73 char wait_uart_rx()
Wayne Roberts 0:e1e70da93044 74 {
Wayne Roberts 0:e1e70da93044 75 char ret;
Wayne Roberts 0:e1e70da93044 76 unsigned foo = uart_rx_buf_in;
Wayne Roberts 0:e1e70da93044 77 while (uart_rx_buf_in == foo) {
Wayne Roberts 0:e1e70da93044 78 log_printf("waiting %u %u\r\n", uart_rx_buf_in, foo);
Wayne Roberts 0:e1e70da93044 79 }
Wayne Roberts 0:e1e70da93044 80
Wayne Roberts 0:e1e70da93044 81 ret = uart_rx_buf[uart_rx_buf_out++];
Wayne Roberts 0:e1e70da93044 82 if (uart_rx_buf_out == UART_RX_BUF_LEN)
Wayne Roberts 0:e1e70da93044 83 uart_rx_buf_out = 0;
Wayne Roberts 0:e1e70da93044 84
Wayne Roberts 0:e1e70da93044 85 return ret;
Wayne Roberts 0:e1e70da93044 86 }
Wayne Roberts 0:e1e70da93044 87 #endif /* MENU_DEBUG */
Wayne Roberts 0:e1e70da93044 88
Wayne Roberts 0:e1e70da93044 89 unsigned lfsr;
Wayne Roberts 0:e1e70da93044 90 #define LFSR_INIT 0x1ff
Wayne Roberts 0:e1e70da93044 91
Wayne Roberts 0:e1e70da93044 92 uint8_t get_pn9_byte()
Wayne Roberts 0:e1e70da93044 93 {
Wayne Roberts 0:e1e70da93044 94 uint8_t ret = 0;
Wayne Roberts 0:e1e70da93044 95 int xor_out;
Wayne Roberts 0:e1e70da93044 96
Wayne Roberts 0:e1e70da93044 97 xor_out = ((lfsr >> 5) & 0xf) ^ (lfsr & 0xf); // four bits at a time
Wayne Roberts 0:e1e70da93044 98 lfsr = (lfsr >> 4) | (xor_out << 5); // four bits at a time
Wayne Roberts 0:e1e70da93044 99
Wayne Roberts 0:e1e70da93044 100 ret |= (lfsr >> 5) & 0x0f;
Wayne Roberts 0:e1e70da93044 101
Wayne Roberts 0:e1e70da93044 102 xor_out = ((lfsr >> 5) & 0xf) ^ (lfsr & 0xf); // four bits at a time
Wayne Roberts 0:e1e70da93044 103 lfsr = (lfsr >> 4) | (xor_out << 5); // four bits at a time
Wayne Roberts 0:e1e70da93044 104
Wayne Roberts 0:e1e70da93044 105 ret |= ((lfsr >> 1) & 0xf0);
Wayne Roberts 0:e1e70da93044 106
Wayne Roberts 0:e1e70da93044 107 return ret;
Wayne Roberts 0:e1e70da93044 108 }
Wayne Roberts 0:e1e70da93044 109
Wayne Roberts 0:e1e70da93044 110 void hw_reset_push()
Wayne Roberts 0:e1e70da93044 111 {
Wayne Roberts 0:e1e70da93044 112 Radio::hw_reset();
Wayne Roberts 0:e1e70da93044 113
Wayne Roberts 0:e1e70da93044 114 Radio::readChip();
Wayne Roberts 0:e1e70da93044 115 menuState.mode = MENUMODE_REINIT_MENU;
Wayne Roberts 0:e1e70da93044 116 }
Wayne Roberts 0:e1e70da93044 117
Wayne Roberts 0:e1e70da93044 118 const button_item_t hw_reset_item = { _ITEM_BUTTON, "hw_reset", hw_reset_push };
Wayne Roberts 0:e1e70da93044 119
Wayne Roberts 0:e1e70da93044 120 void clearIrqs_push()
Wayne Roberts 0:e1e70da93044 121 {
Wayne Roberts 0:e1e70da93044 122 Radio::clearIrqFlags();
Wayne Roberts 0:e1e70da93044 123 }
Wayne Roberts 0:e1e70da93044 124
Wayne Roberts 0:e1e70da93044 125 const button_item_t clearirqs_item = { _ITEM_BUTTON, "clearIrqs", clearIrqs_push };
Wayne Roberts 0:e1e70da93044 126
Wayne Roberts 0:e1e70da93044 127 const dropdown_item_t pktType_item = { _ITEM_DROPDOWN, Radio::pktType_strs, Radio::pktType_strs, Radio::pktType_read, Radio::pktType_write};
Wayne Roberts 0:e1e70da93044 128
Wayne Roberts 0:e1e70da93044 129
Wayne Roberts 0:e1e70da93044 130 unsigned msgType_read(bool fw)
Wayne Roberts 0:e1e70da93044 131 {
Wayne Roberts 0:e1e70da93044 132 return msg_type;
Wayne Roberts 0:e1e70da93044 133 }
Wayne Roberts 0:e1e70da93044 134
Wayne Roberts 0:e1e70da93044 135 menuMode_e msgType_write(unsigned widx)
Wayne Roberts 0:e1e70da93044 136 {
Wayne Roberts 0:e1e70da93044 137 msg_type = (msgType_e)widx;
Wayne Roberts 0:e1e70da93044 138
Wayne Roberts 0:e1e70da93044 139 if (msg_type == MSG_TYPE_PER) {
Wayne Roberts 0:e1e70da93044 140 flags.pingpongEnable = 0;
Wayne Roberts 0:e1e70da93044 141 if (Radio::get_payload_length() < 7)
Wayne Roberts 0:e1e70da93044 142 Radio::set_payload_length(7);
Wayne Roberts 0:e1e70da93044 143 } else if (msg_type == MSG_TYPE_PINGPONG) {
Wayne Roberts 0:e1e70da93044 144 if (Radio::get_payload_length() != 12)
Wayne Roberts 0:e1e70da93044 145 Radio::set_payload_length(12);
Wayne Roberts 0:e1e70da93044 146 } else if (msg_type == MSG_TYPE_PACKET) {
Wayne Roberts 0:e1e70da93044 147 flags.pingpongEnable = 0;
Wayne Roberts 0:e1e70da93044 148 }
Wayne Roberts 0:e1e70da93044 149
Wayne Roberts 0:e1e70da93044 150 return MENUMODE_REINIT_MENU;
Wayne Roberts 0:e1e70da93044 151 }
Wayne Roberts 0:e1e70da93044 152
Wayne Roberts 0:e1e70da93044 153 const char* const msgType_strs[] = {
Wayne Roberts 0:e1e70da93044 154 "PACKET ",
Wayne Roberts 0:e1e70da93044 155 "PER ",
Wayne Roberts 0:e1e70da93044 156 "PINGPONG",
Wayne Roberts 0:e1e70da93044 157 NULL
Wayne Roberts 0:e1e70da93044 158 };
Wayne Roberts 0:e1e70da93044 159
Wayne Roberts 0:e1e70da93044 160 const dropdown_item_t msgType_item = { _ITEM_DROPDOWN, msgType_strs, msgType_strs, msgType_read, msgType_write};
Wayne Roberts 0:e1e70da93044 161
Wayne Roberts 0:e1e70da93044 162 #define LAST_CHIP_MENU_ROW (MAX_MENU_ROWS-5)
Wayne Roberts 0:e1e70da93044 163
Wayne Roberts 0:e1e70da93044 164 const value_item_t tx_payload_length_item = { _ITEM_VALUE, 5, Radio::tx_payload_length_print, Radio::tx_payload_length_write};
Wayne Roberts 0:e1e70da93044 165
Wayne Roberts 0:e1e70da93044 166 void pn9_push()
Wayne Roberts 0:e1e70da93044 167 {
Wayne Roberts 0:e1e70da93044 168 uint8_t i, len = Radio::get_payload_length();
Wayne Roberts 0:e1e70da93044 169 for (i = 0; i < len; i++)
Wayne Roberts 0:e1e70da93044 170 Radio::radio.tx_buf[i] = get_pn9_byte();
Wayne Roberts 0:e1e70da93044 171 }
Wayne Roberts 0:e1e70da93044 172
Wayne Roberts 0:e1e70da93044 173 const button_item_t tx_payload_pn9_item = { _ITEM_BUTTON, "PN9", pn9_push };
Wayne Roberts 0:e1e70da93044 174
Wayne Roberts 0:e1e70da93044 175 void regAddr_print()
Wayne Roberts 0:e1e70da93044 176 {
Wayne Roberts 0:e1e70da93044 177 if (regAddr != -1)
Wayne Roberts 0:e1e70da93044 178 pc.printf("%x", regAddr);
Wayne Roberts 0:e1e70da93044 179 }
Wayne Roberts 0:e1e70da93044 180
Wayne Roberts 0:e1e70da93044 181 bool regAddr_write(const char* txt)
Wayne Roberts 0:e1e70da93044 182 {
Wayne Roberts 0:e1e70da93044 183 sscanf(txt, "%x", &regAddr);
Wayne Roberts 0:e1e70da93044 184 return false;
Wayne Roberts 0:e1e70da93044 185 }
Wayne Roberts 0:e1e70da93044 186
Wayne Roberts 0:e1e70da93044 187 const value_item_t regAddr_item = { _ITEM_VALUE, 5, regAddr_print, regAddr_write};
Wayne Roberts 0:e1e70da93044 188
Wayne Roberts 0:e1e70da93044 189 void regValue_print()
Wayne Roberts 0:e1e70da93044 190 {
Wayne Roberts 0:e1e70da93044 191 if (regAddr != -1) {
Wayne Roberts 0:e1e70da93044 192 pc.printf("%x", Radio::read_register(regAddr));
Wayne Roberts 0:e1e70da93044 193 }
Wayne Roberts 0:e1e70da93044 194 }
Wayne Roberts 0:e1e70da93044 195
Wayne Roberts 0:e1e70da93044 196 bool regValue_write(const char* txt)
Wayne Roberts 0:e1e70da93044 197 {
Wayne Roberts 0:e1e70da93044 198 unsigned val;
Wayne Roberts 0:e1e70da93044 199 sscanf(txt, "%x", &val);
Wayne Roberts 0:e1e70da93044 200 if (regAddr != -1) {
Wayne Roberts 0:e1e70da93044 201 Radio::write_register(regAddr, val);
Wayne Roberts 0:e1e70da93044 202 }
Wayne Roberts 0:e1e70da93044 203 return false;
Wayne Roberts 0:e1e70da93044 204 }
Wayne Roberts 0:e1e70da93044 205
Wayne Roberts 0:e1e70da93044 206 const value_item_t regValue_item = { _ITEM_VALUE, 5, regValue_print, regValue_write};
Wayne Roberts 0:e1e70da93044 207
Wayne Roberts 0:e1e70da93044 208 void tx_payload_print()
Wayne Roberts 0:e1e70da93044 209 {
Wayne Roberts 0:e1e70da93044 210 uint8_t i, len = Radio::get_payload_length();
Wayne Roberts 0:e1e70da93044 211 for (i = 0; i < len; i++)
Wayne Roberts 0:e1e70da93044 212 pc.printf("%02x ", Radio::radio.tx_buf[i]);
Wayne Roberts 0:e1e70da93044 213 }
Wayne Roberts 0:e1e70da93044 214
Wayne Roberts 0:e1e70da93044 215 bool tx_payload_write(const char* txt)
Wayne Roberts 0:e1e70da93044 216 {
Wayne Roberts 0:e1e70da93044 217 unsigned o, i = 0, pktidx = 0;
Wayne Roberts 0:e1e70da93044 218 while (i < entry_buf_idx) {
Wayne Roberts 0:e1e70da93044 219 sscanf(entry_buf+i, "%02x", &o);
Wayne Roberts 0:e1e70da93044 220 pc.printf("%02x ", o);
Wayne Roberts 0:e1e70da93044 221 i += 2;
Wayne Roberts 0:e1e70da93044 222 Radio::radio.tx_buf[pktidx++] = o;
Wayne Roberts 0:e1e70da93044 223 while (entry_buf[i] == ' ' && i < entry_buf_idx)
Wayne Roberts 0:e1e70da93044 224 i++;
Wayne Roberts 0:e1e70da93044 225 }
Wayne Roberts 0:e1e70da93044 226 log_printf("set payload len %u\r\n", pktidx);
Wayne Roberts 0:e1e70da93044 227 Radio::set_payload_length(pktidx);
Wayne Roberts 0:e1e70da93044 228 return true;
Wayne Roberts 0:e1e70da93044 229 }
Wayne Roberts 0:e1e70da93044 230
Wayne Roberts 0:e1e70da93044 231 const value_item_t tx_payload_item = { _ITEM_VALUE, 80, tx_payload_print, tx_payload_write};
Wayne Roberts 0:e1e70da93044 232
Wayne Roberts 0:e1e70da93044 233 void txpkt_push()
Wayne Roberts 0:e1e70da93044 234 {
Wayne Roberts 0:e1e70da93044 235 Radio::txPkt();
Wayne Roberts 0:e1e70da93044 236 }
Wayne Roberts 0:e1e70da93044 237
Wayne Roberts 0:e1e70da93044 238 const button_item_t tx_pkt_item = { _ITEM_BUTTON, "TXPKT", txpkt_push };
Wayne Roberts 0:e1e70da93044 239
Wayne Roberts 0:e1e70da93044 240 void rxpkt_push()
Wayne Roberts 0:e1e70da93044 241 {
Wayne Roberts 0:e1e70da93044 242 Radio::Rx();
Wayne Roberts 0:e1e70da93044 243 menuState.mode = MENUMODE_REDRAW;
Wayne Roberts 0:e1e70da93044 244 }
Wayne Roberts 0:e1e70da93044 245 const button_item_t rx_pkt_item = { _ITEM_BUTTON, "RXPKT", rxpkt_push };
Wayne Roberts 0:e1e70da93044 246
Wayne Roberts 0:e1e70da93044 247 const dropdown_item_t opmode_item = { _ITEM_DROPDOWN, Radio::opmode_status_strs, Radio::opmode_select_strs, Radio::opmode_read, Radio::opmode_write };
Wayne Roberts 0:e1e70da93044 248
Wayne Roberts 0:e1e70da93044 249 void tx_carrier_push()
Wayne Roberts 0:e1e70da93044 250 {
Wayne Roberts 0:e1e70da93044 251 Radio::tx_carrier();
Wayne Roberts 0:e1e70da93044 252 }
Wayne Roberts 0:e1e70da93044 253 const button_item_t tx_carrier_item = { _ITEM_BUTTON, "TX_CARRIER", tx_carrier_push };
Wayne Roberts 0:e1e70da93044 254
Wayne Roberts 0:e1e70da93044 255 void tx_preamble_push()
Wayne Roberts 0:e1e70da93044 256 {
Wayne Roberts 0:e1e70da93044 257 Radio::tx_preamble();
Wayne Roberts 0:e1e70da93044 258 }
Wayne Roberts 0:e1e70da93044 259 const button_item_t tx_preamble_item = { _ITEM_BUTTON, "TX_PREAMBLE", tx_preamble_push };
Wayne Roberts 0:e1e70da93044 260
Wayne Roberts 0:e1e70da93044 261 bool accel_en_read()
Wayne Roberts 0:e1e70da93044 262 {
Wayne Roberts 0:e1e70da93044 263 uint8_t status;
Wayne Roberts 0:e1e70da93044 264 accel_is_enabled(&status);
Wayne Roberts 0:e1e70da93044 265 return status;
Wayne Roberts 0:e1e70da93044 266 }
Wayne Roberts 0:e1e70da93044 267
Wayne Roberts 0:e1e70da93044 268 bool accel_tx_en_read()
Wayne Roberts 0:e1e70da93044 269 {
Wayne Roberts 0:e1e70da93044 270 uint8_t status;
Wayne Roberts 0:e1e70da93044 271 accel_is_enabled(&status);
Wayne Roberts 0:e1e70da93044 272 return status && accel_tx_en;
Wayne Roberts 0:e1e70da93044 273 }
Wayne Roberts 0:e1e70da93044 274
Wayne Roberts 0:e1e70da93044 275
Wayne Roberts 0:e1e70da93044 276 bool accel_en_push()
Wayne Roberts 0:e1e70da93044 277 {
Wayne Roberts 0:e1e70da93044 278 uint8_t status;
Wayne Roberts 0:e1e70da93044 279 accel_is_enabled(&status);
Wayne Roberts 0:e1e70da93044 280
Wayne Roberts 0:e1e70da93044 281 accel_tx_en = false;
Wayne Roberts 0:e1e70da93044 282 if (status)
Wayne Roberts 0:e1e70da93044 283 accel_enable(false);
Wayne Roberts 0:e1e70da93044 284 else
Wayne Roberts 0:e1e70da93044 285 accel_enable(true);
Wayne Roberts 0:e1e70da93044 286
Wayne Roberts 0:e1e70da93044 287 accel_is_enabled(&status);
Wayne Roberts 0:e1e70da93044 288 return status;
Wayne Roberts 0:e1e70da93044 289 }
Wayne Roberts 0:e1e70da93044 290
Wayne Roberts 0:e1e70da93044 291 bool accel_tx_en_push()
Wayne Roberts 0:e1e70da93044 292 {
Wayne Roberts 0:e1e70da93044 293 uint8_t status;
Wayne Roberts 0:e1e70da93044 294 accel_is_enabled(&status);
Wayne Roberts 0:e1e70da93044 295
Wayne Roberts 0:e1e70da93044 296 accel_tx_en = true;
Wayne Roberts 0:e1e70da93044 297 if (status)
Wayne Roberts 0:e1e70da93044 298 accel_enable(false);
Wayne Roberts 0:e1e70da93044 299 else
Wayne Roberts 0:e1e70da93044 300 accel_enable(true);
Wayne Roberts 0:e1e70da93044 301
Wayne Roberts 0:e1e70da93044 302 accel_is_enabled(&status);
Wayne Roberts 0:e1e70da93044 303 return status;
Wayne Roberts 0:e1e70da93044 304 }
Wayne Roberts 0:e1e70da93044 305
Wayne Roberts 0:e1e70da93044 306 const toggle_item_t accel_enable_item = { _ITEM_TOGGLE, "enable", NULL, accel_en_read, accel_en_push};
Wayne Roberts 0:e1e70da93044 307 const toggle_item_t accel_tx_enable_item = { _ITEM_TOGGLE, "tx_enable", NULL, accel_tx_en_read, accel_tx_en_push};
Wayne Roberts 0:e1e70da93044 308
Wayne Roberts 0:e1e70da93044 309 const menu_t lis12dh12_menu[] = {
Wayne Roberts 0:e1e70da93044 310 { {LAST_CHIP_MENU_ROW-1, 1}, "LIS12DH12 ", &accel_enable_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 311 { {LAST_CHIP_MENU_ROW-1, 24}, NULL, &accel_tx_enable_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 312 };
Wayne Roberts 0:e1e70da93044 313
Wayne Roberts 0:e1e70da93044 314
Wayne Roberts 0:e1e70da93044 315 #ifdef PHOTOS_PIN
Wayne Roberts 0:e1e70da93044 316 void photos_push()
Wayne Roberts 0:e1e70da93044 317 {
Wayne Roberts 0:e1e70da93044 318 uint16_t val = photos.read_u16();
Wayne Roberts 0:e1e70da93044 319 log_printf("photos %u\r\n", val);
Wayne Roberts 0:e1e70da93044 320 }
Wayne Roberts 0:e1e70da93044 321
Wayne Roberts 0:e1e70da93044 322 void tx_photos_push()
Wayne Roberts 0:e1e70da93044 323 {
Wayne Roberts 0:e1e70da93044 324 uint16_t val = photos.read_u16();
Wayne Roberts 0:e1e70da93044 325 log_printf("Tx photos %u\r\n", val);
Wayne Roberts 0:e1e70da93044 326 Radio::radio.tx_buf[0] = CMD_PHOTOS;
Wayne Roberts 0:e1e70da93044 327 Radio::set_payload_length(sizeof(uint16_t)+1);
Wayne Roberts 0:e1e70da93044 328 memcpy(&Radio::radio.tx_buf[1], &val, sizeof(uint16_t));
Wayne Roberts 0:e1e70da93044 329 Radio::txPkt();
Wayne Roberts 0:e1e70da93044 330 }
Wayne Roberts 0:e1e70da93044 331
Wayne Roberts 0:e1e70da93044 332 const button_item_t photos_item = { _ITEM_BUTTON, "photos", photos_push };
Wayne Roberts 0:e1e70da93044 333 const button_item_t tx_photos_item = { _ITEM_BUTTON, "tx_photos", tx_photos_push };
Wayne Roberts 0:e1e70da93044 334
Wayne Roberts 0:e1e70da93044 335 const menu_t photos_menu[] = {
Wayne Roberts 0:e1e70da93044 336 { {LAST_CHIP_MENU_ROW-2, 1}, "PHOTOS ", &photos_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 337 { {LAST_CHIP_MENU_ROW-2, 24}, NULL, &tx_photos_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 338 };
Wayne Roberts 0:e1e70da93044 339 #endif /* PHOTOS_PIN */
Wayne Roberts 0:e1e70da93044 340
Wayne Roberts 0:e1e70da93044 341 void temperature_push()
Wayne Roberts 0:e1e70da93044 342 {
Wayne Roberts 0:e1e70da93044 343 displayFloatToInt_t val;
Wayne Roberts 0:e1e70da93044 344 demo_sample_temp(&val);
Wayne Roberts 0:e1e70da93044 345 }
Wayne Roberts 0:e1e70da93044 346
Wayne Roberts 0:e1e70da93044 347 void pressure_push()
Wayne Roberts 0:e1e70da93044 348 {
Wayne Roberts 0:e1e70da93044 349 displayFloatToInt_t val;
Wayne Roberts 0:e1e70da93044 350 demo_sample_pressure(&val);
Wayne Roberts 0:e1e70da93044 351 }
Wayne Roberts 0:e1e70da93044 352
Wayne Roberts 0:e1e70da93044 353 void tx_temp_push()
Wayne Roberts 0:e1e70da93044 354 {
Wayne Roberts 0:e1e70da93044 355 displayFloatToInt_t val;
Wayne Roberts 0:e1e70da93044 356 demo_sample_temp(&val);
Wayne Roberts 0:e1e70da93044 357
Wayne Roberts 0:e1e70da93044 358 Radio::set_payload_length(sizeof(displayFloatToInt_t)+1);
Wayne Roberts 0:e1e70da93044 359
Wayne Roberts 0:e1e70da93044 360 Radio::radio.tx_buf[0] = CMD_TEMP;
Wayne Roberts 0:e1e70da93044 361 memcpy(&Radio::radio.tx_buf[1], &val, sizeof(displayFloatToInt_t));
Wayne Roberts 0:e1e70da93044 362
Wayne Roberts 0:e1e70da93044 363 Radio::txPkt();
Wayne Roberts 0:e1e70da93044 364 }
Wayne Roberts 0:e1e70da93044 365
Wayne Roberts 0:e1e70da93044 366 void tx_pressure_push()
Wayne Roberts 0:e1e70da93044 367 {
Wayne Roberts 0:e1e70da93044 368 displayFloatToInt_t val;
Wayne Roberts 0:e1e70da93044 369 demo_sample_pressure(&val);
Wayne Roberts 0:e1e70da93044 370
Wayne Roberts 0:e1e70da93044 371 Radio::set_payload_length(sizeof(displayFloatToInt_t)+1);
Wayne Roberts 0:e1e70da93044 372
Wayne Roberts 0:e1e70da93044 373 Radio::radio.tx_buf[0] = CMD_PRES;
Wayne Roberts 0:e1e70da93044 374 memcpy(&Radio::radio.tx_buf[1], &val, sizeof(displayFloatToInt_t));
Wayne Roberts 0:e1e70da93044 375
Wayne Roberts 0:e1e70da93044 376 Radio::txPkt();
Wayne Roberts 0:e1e70da93044 377 }
Wayne Roberts 0:e1e70da93044 378
Wayne Roberts 0:e1e70da93044 379
Wayne Roberts 0:e1e70da93044 380 const button_item_t temperature_item = { _ITEM_BUTTON, "temperature", temperature_push };
Wayne Roberts 0:e1e70da93044 381 const button_item_t pressure_item = { _ITEM_BUTTON, "pressure", pressure_push };
Wayne Roberts 0:e1e70da93044 382 const button_item_t tx_temp_item = { _ITEM_BUTTON, "tx_temp", tx_temp_push };
Wayne Roberts 0:e1e70da93044 383 const button_item_t tx_pressure_item = { _ITEM_BUTTON, "tx_pressure", tx_pressure_push };
Wayne Roberts 0:e1e70da93044 384
Wayne Roberts 0:e1e70da93044 385
Wayne Roberts 0:e1e70da93044 386 const menu_t lps22hh_menu[] = {
Wayne Roberts 0:e1e70da93044 387 { {LAST_CHIP_MENU_ROW, 1}, "LPS22HH ", &temperature_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 388 { {LAST_CHIP_MENU_ROW, 22}, NULL, &pressure_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 389 { {LAST_CHIP_MENU_ROW, 31}, NULL, &tx_temp_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 390 { {LAST_CHIP_MENU_ROW, 40}, NULL, &tx_pressure_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 391 };
Wayne Roberts 0:e1e70da93044 392
Wayne Roberts 0:e1e70da93044 393 const menu_t msg_pkt_menu[] = {
Wayne Roberts 0:e1e70da93044 394 { {LAST_CHIP_MENU_ROW+1, 1}, "tx payload length:", &tx_payload_length_item, FLAG_MSGTYPE_PKT },
Wayne Roberts 0:e1e70da93044 395 { {LAST_CHIP_MENU_ROW+1, 25}, NULL, &tx_payload_pn9_item, FLAG_MSGTYPE_PKT, &tx_payload_item },
Wayne Roberts 0:e1e70da93044 396 { {LAST_CHIP_MENU_ROW+1, 40}, "regAddr:", &regAddr_item, FLAG_MSGTYPE_PKT, &regValue_item },
Wayne Roberts 0:e1e70da93044 397 { {LAST_CHIP_MENU_ROW+1, 53}, "regValue:", &regValue_item, FLAG_MSGTYPE_PKT, },
Wayne Roberts 0:e1e70da93044 398 { {LAST_CHIP_MENU_ROW+2, 1}, NULL, &tx_payload_item, FLAG_MSGTYPE_PKT },
Wayne Roberts 0:e1e70da93044 399 { {LAST_CHIP_MENU_ROW+3, 1}, NULL, &tx_pkt_item, FLAG_MSGTYPE_PKT, &opmode_item },
Wayne Roberts 0:e1e70da93044 400 { {LAST_CHIP_MENU_ROW+3, 10}, NULL, &rx_pkt_item, FLAG_MSGTYPE_PKT },
Wayne Roberts 0:e1e70da93044 401 { {LAST_CHIP_MENU_ROW+3, 20}, NULL, &tx_carrier_item, FLAG_MSGTYPE_PKT, &opmode_item },
Wayne Roberts 0:e1e70da93044 402 { {LAST_CHIP_MENU_ROW+3, 45}, NULL, &tx_preamble_item, FLAG_MSGTYPE_PKT, &opmode_item },
Wayne Roberts 0:e1e70da93044 403
Wayne Roberts 0:e1e70da93044 404 { {0, 0}, NULL, NULL }
Wayne Roberts 0:e1e70da93044 405 };
Wayne Roberts 0:e1e70da93044 406
Wayne Roberts 0:e1e70da93044 407 unsigned tx_ipd_ms;
Wayne Roberts 0:e1e70da93044 408 Timeout mbedTimeout;
Wayne Roberts 0:e1e70da93044 409 unsigned MaxNumPacket;
Wayne Roberts 0:e1e70da93044 410 unsigned CntPacketTx;
Wayne Roberts 0:e1e70da93044 411 unsigned PacketRxSequencePrev;
Wayne Roberts 0:e1e70da93044 412 unsigned CntPacketRxKO;
Wayne Roberts 0:e1e70da93044 413 unsigned CntPacketRxOK;
Wayne Roberts 0:e1e70da93044 414 unsigned RxTimeOutCount;
Wayne Roberts 0:e1e70da93044 415 unsigned receivedCntPacket;
Wayne Roberts 0:e1e70da93044 416
Wayne Roberts 0:e1e70da93044 417 void do_next_tx ()
Wayne Roberts 0:e1e70da93044 418 {
Wayne Roberts 0:e1e70da93044 419 Radio::radio.tx_buf[0] = CntPacketTx >> 24;
Wayne Roberts 0:e1e70da93044 420 Radio::radio.tx_buf[1] = CntPacketTx >> 16;
Wayne Roberts 0:e1e70da93044 421 Radio::radio.tx_buf[2] = CntPacketTx >> 8;
Wayne Roberts 0:e1e70da93044 422 Radio::radio.tx_buf[3] = CntPacketTx;
Wayne Roberts 0:e1e70da93044 423
Wayne Roberts 0:e1e70da93044 424 Radio::radio.tx_buf[4] = PerMsg[0];
Wayne Roberts 0:e1e70da93044 425 Radio::radio.tx_buf[5] = PerMsg[1];
Wayne Roberts 0:e1e70da93044 426 Radio::radio.tx_buf[6] = PerMsg[2];
Wayne Roberts 0:e1e70da93044 427
Wayne Roberts 0:e1e70da93044 428 Radio::txPkt();
Wayne Roberts 0:e1e70da93044 429 }
Wayne Roberts 0:e1e70da93044 430
Wayne Roberts 0:e1e70da93044 431 void next_tx_callback()
Wayne Roberts 0:e1e70da93044 432 {
Wayne Roberts 0:e1e70da93044 433 flags.do_next_tx = 1;
Wayne Roberts 0:e1e70da93044 434 }
Wayne Roberts 0:e1e70da93044 435
Wayne Roberts 0:e1e70da93044 436
Wayne Roberts 0:e1e70da93044 437 void pertx_push()
Wayne Roberts 0:e1e70da93044 438 {
Wayne Roberts 0:e1e70da93044 439 CntPacketTx = 1; // PacketRxSequencePrev initialized to 0 on receiver
Wayne Roberts 0:e1e70da93044 440
Wayne Roberts 0:e1e70da93044 441 log_printf("do perTx\r\n");
Wayne Roberts 0:e1e70da93044 442
Wayne Roberts 0:e1e70da93044 443 next_tx_callback();
Wayne Roberts 0:e1e70da93044 444 }
Wayne Roberts 0:e1e70da93044 445
Wayne Roberts 0:e1e70da93044 446
Wayne Roberts 0:e1e70da93044 447 const button_item_t pertx_item = { _ITEM_BUTTON, "PERTX", pertx_push };
Wayne Roberts 0:e1e70da93044 448
Wayne Roberts 0:e1e70da93044 449 void tx_ipd_print()
Wayne Roberts 0:e1e70da93044 450 {
Wayne Roberts 0:e1e70da93044 451 pc.printf("%u", tx_ipd_ms);
Wayne Roberts 0:e1e70da93044 452 }
Wayne Roberts 0:e1e70da93044 453
Wayne Roberts 0:e1e70da93044 454 bool tx_ipd_write(const char* valStr)
Wayne Roberts 0:e1e70da93044 455 {
Wayne Roberts 0:e1e70da93044 456 sscanf(valStr, "%u", &tx_ipd_ms);
Wayne Roberts 0:e1e70da93044 457 return false;
Wayne Roberts 0:e1e70da93044 458 }
Wayne Roberts 0:e1e70da93044 459
Wayne Roberts 0:e1e70da93044 460 value_item_t per_ipd_item = { _ITEM_VALUE, 4, tx_ipd_print, tx_ipd_write };
Wayne Roberts 0:e1e70da93044 461
Wayne Roberts 0:e1e70da93044 462 void numpkts_print()
Wayne Roberts 0:e1e70da93044 463 {
Wayne Roberts 0:e1e70da93044 464 pc.printf("%u", MaxNumPacket);
Wayne Roberts 0:e1e70da93044 465 }
Wayne Roberts 0:e1e70da93044 466
Wayne Roberts 0:e1e70da93044 467 bool numpkts_write(const char* valStr)
Wayne Roberts 0:e1e70da93044 468 {
Wayne Roberts 0:e1e70da93044 469 sscanf(valStr, "%u", &MaxNumPacket);
Wayne Roberts 0:e1e70da93044 470 return false;
Wayne Roberts 0:e1e70da93044 471 }
Wayne Roberts 0:e1e70da93044 472
Wayne Roberts 0:e1e70da93044 473 value_item_t per_numpkts_item = { _ITEM_VALUE, 6, numpkts_print, numpkts_write };
Wayne Roberts 0:e1e70da93044 474
Wayne Roberts 0:e1e70da93044 475 void perrx_push()
Wayne Roberts 0:e1e70da93044 476 {
Wayne Roberts 0:e1e70da93044 477 PacketRxSequencePrev = 0;
Wayne Roberts 0:e1e70da93044 478 CntPacketRxKO = 0;
Wayne Roberts 0:e1e70da93044 479 CntPacketRxOK = 0;
Wayne Roberts 0:e1e70da93044 480 RxTimeOutCount = 0;
Wayne Roberts 0:e1e70da93044 481
Wayne Roberts 0:e1e70da93044 482 Radio::Rx();
Wayne Roberts 0:e1e70da93044 483 }
Wayne Roberts 0:e1e70da93044 484
Wayne Roberts 0:e1e70da93044 485 const button_item_t perrx_item = { _ITEM_BUTTON, "PERRX", perrx_push };
Wayne Roberts 0:e1e70da93044 486
Wayne Roberts 0:e1e70da93044 487 void per_reset_push()
Wayne Roberts 0:e1e70da93044 488 {
Wayne Roberts 0:e1e70da93044 489 PacketRxSequencePrev = 0;
Wayne Roberts 0:e1e70da93044 490 CntPacketRxKO = 0;
Wayne Roberts 0:e1e70da93044 491 CntPacketRxOK = 0;
Wayne Roberts 0:e1e70da93044 492 RxTimeOutCount = 0;
Wayne Roberts 0:e1e70da93044 493 }
Wayne Roberts 0:e1e70da93044 494
Wayne Roberts 0:e1e70da93044 495 const button_item_t per_clear_item = { _ITEM_BUTTON, "resetCount", per_reset_push };
Wayne Roberts 0:e1e70da93044 496
Wayne Roberts 0:e1e70da93044 497 const menu_t msg_per_menu[] = {
Wayne Roberts 0:e1e70da93044 498 { {LAST_CHIP_MENU_ROW+3, 1}, NULL, &pertx_item, FLAG_MSGTYPE_PER },
Wayne Roberts 0:e1e70da93044 499 { {LAST_CHIP_MENU_ROW+3, 12}, "TX IPD ms:", &per_ipd_item, FLAG_MSGTYPE_PER },
Wayne Roberts 0:e1e70da93044 500 { {LAST_CHIP_MENU_ROW+3, 26}, "numPkts:", &per_numpkts_item, FLAG_MSGTYPE_PER },
Wayne Roberts 0:e1e70da93044 501 { {LAST_CHIP_MENU_ROW+3, 40}, NULL, &perrx_item, FLAG_MSGTYPE_PER, &opmode_item },
Wayne Roberts 0:e1e70da93044 502 { {LAST_CHIP_MENU_ROW+3, 50}, NULL, &per_clear_item, FLAG_MSGTYPE_PER, &opmode_item },
Wayne Roberts 0:e1e70da93044 503 { {0, 0}, NULL, NULL }
Wayne Roberts 0:e1e70da93044 504 };
Wayne Roberts 0:e1e70da93044 505
Wayne Roberts 0:e1e70da93044 506 void SendPong()
Wayne Roberts 0:e1e70da93044 507 {
Wayne Roberts 0:e1e70da93044 508 unsigned failCnt = CntPacketRxKO + RxTimeOutCount;
Wayne Roberts 0:e1e70da93044 509
Wayne Roberts 0:e1e70da93044 510 /* ping slave tx */
Wayne Roberts 0:e1e70da93044 511 log_printf("ACK PKT%u\r\n", receivedCntPacket);
Wayne Roberts 0:e1e70da93044 512
Wayne Roberts 0:e1e70da93044 513 Radio::radio.tx_buf[ 0] = receivedCntPacket >> 24;
Wayne Roberts 0:e1e70da93044 514 Radio::radio.tx_buf[ 1] = receivedCntPacket >> 16;
Wayne Roberts 0:e1e70da93044 515 Radio::radio.tx_buf[ 2] = receivedCntPacket >> 8;
Wayne Roberts 0:e1e70da93044 516 Radio::radio.tx_buf[ 3] = receivedCntPacket;
Wayne Roberts 0:e1e70da93044 517 Radio::radio.tx_buf[ 4] = failCnt >> 24;
Wayne Roberts 0:e1e70da93044 518 Radio::radio.tx_buf[ 5] = failCnt >> 16;
Wayne Roberts 0:e1e70da93044 519 Radio::radio.tx_buf[ 6] = failCnt >> 8;
Wayne Roberts 0:e1e70da93044 520 Radio::radio.tx_buf[ 7] = failCnt;
Wayne Roberts 0:e1e70da93044 521 Radio::radio.tx_buf[ 8] = PongMsg[0];
Wayne Roberts 0:e1e70da93044 522 Radio::radio.tx_buf[ 9] = PongMsg[1];
Wayne Roberts 0:e1e70da93044 523 Radio::radio.tx_buf[10] = PongMsg[2];
Wayne Roberts 0:e1e70da93044 524 Radio::radio.tx_buf[11] = PongMsg[3];
Wayne Roberts 0:e1e70da93044 525
Wayne Roberts 0:e1e70da93044 526 Radio::txPkt();
Wayne Roberts 0:e1e70da93044 527 }
Wayne Roberts 0:e1e70da93044 528
Wayne Roberts 0:e1e70da93044 529 void SendPing()
Wayne Roberts 0:e1e70da93044 530 {
Wayne Roberts 0:e1e70da93044 531 /* ping master tx */
Wayne Roberts 0:e1e70da93044 532
Wayne Roberts 0:e1e70da93044 533 log_printf("MASTER > PING PKT%u\r\n", CntPacketTx);
Wayne Roberts 0:e1e70da93044 534 Radio::radio.tx_buf[0] = CntPacketTx >> 24;
Wayne Roberts 0:e1e70da93044 535 Radio::radio.tx_buf[1] = CntPacketTx >> 16;
Wayne Roberts 0:e1e70da93044 536 Radio::radio.tx_buf[2] = CntPacketTx >> 8;
Wayne Roberts 0:e1e70da93044 537 Radio::radio.tx_buf[3] = CntPacketTx;
Wayne Roberts 0:e1e70da93044 538 Radio::radio.tx_buf[4] = PingMsg[0];
Wayne Roberts 0:e1e70da93044 539 Radio::radio.tx_buf[5] = PingMsg[1];
Wayne Roberts 0:e1e70da93044 540 Radio::radio.tx_buf[6] = PingMsg[2];
Wayne Roberts 0:e1e70da93044 541 Radio::radio.tx_buf[7] = PingMsg[3];
Wayne Roberts 0:e1e70da93044 542
Wayne Roberts 0:e1e70da93044 543 Radio::txPkt();
Wayne Roberts 0:e1e70da93044 544 }
Wayne Roberts 0:e1e70da93044 545
Wayne Roberts 0:e1e70da93044 546 void
Wayne Roberts 0:e1e70da93044 547 pingpong_start_push()
Wayne Roberts 0:e1e70da93044 548 {
Wayne Roberts 0:e1e70da93044 549 CntPacketTx = 1;
Wayne Roberts 0:e1e70da93044 550 CntPacketRxKO = 0;
Wayne Roberts 0:e1e70da93044 551 CntPacketRxOK = 0;
Wayne Roberts 0:e1e70da93044 552 RxTimeOutCount = 0;
Wayne Roberts 0:e1e70da93044 553 receivedCntPacket = 0;
Wayne Roberts 0:e1e70da93044 554
Wayne Roberts 0:e1e70da93044 555 flags.send_ping = 1;
Wayne Roberts 0:e1e70da93044 556
Wayne Roberts 0:e1e70da93044 557 flags.ping_master = 1;
Wayne Roberts 0:e1e70da93044 558
Wayne Roberts 0:e1e70da93044 559 flags.pingpongEnable = 1;
Wayne Roberts 0:e1e70da93044 560 log_printf("ping start\r\n");
Wayne Roberts 0:e1e70da93044 561 }
Wayne Roberts 0:e1e70da93044 562
Wayne Roberts 0:e1e70da93044 563 const button_item_t pingpong_start_item = { _ITEM_BUTTON, "START", pingpong_start_push };
Wayne Roberts 0:e1e70da93044 564
Wayne Roberts 0:e1e70da93044 565 void
Wayne Roberts 0:e1e70da93044 566 pingpong_stop_push ()
Wayne Roberts 0:e1e70da93044 567 {
Wayne Roberts 0:e1e70da93044 568 flags.pingpongEnable = 0;
Wayne Roberts 0:e1e70da93044 569 }
Wayne Roberts 0:e1e70da93044 570
Wayne Roberts 0:e1e70da93044 571 const button_item_t pingpong_stop_item = { _ITEM_BUTTON, "STOP", pingpong_stop_push };
Wayne Roberts 0:e1e70da93044 572
Wayne Roberts 0:e1e70da93044 573 const menu_t msg_pingpong_menu[] = {
Wayne Roberts 0:e1e70da93044 574 { {LAST_CHIP_MENU_ROW+3, 1}, NULL, &pingpong_start_item, FLAG_MSGTYPE_PING },
Wayne Roberts 0:e1e70da93044 575 { {LAST_CHIP_MENU_ROW+3, 15}, NULL, &pingpong_stop_item, FLAG_MSGTYPE_PING },
Wayne Roberts 0:e1e70da93044 576 { {0, 0}, NULL, NULL }
Wayne Roberts 0:e1e70da93044 577 };
Wayne Roberts 0:e1e70da93044 578
Wayne Roberts 0:e1e70da93044 579 const menu_t* get_msg_menu()
Wayne Roberts 0:e1e70da93044 580 {
Wayne Roberts 0:e1e70da93044 581 switch (msg_type) {
Wayne Roberts 0:e1e70da93044 582 case MSG_TYPE_PACKET:
Wayne Roberts 0:e1e70da93044 583 return msg_pkt_menu;
Wayne Roberts 0:e1e70da93044 584 case MSG_TYPE_PER:
Wayne Roberts 0:e1e70da93044 585 return msg_per_menu;
Wayne Roberts 0:e1e70da93044 586 case MSG_TYPE_PINGPONG:
Wayne Roberts 0:e1e70da93044 587 return msg_pingpong_menu;
Wayne Roberts 0:e1e70da93044 588 }
Wayne Roberts 0:e1e70da93044 589 return NULL;
Wayne Roberts 0:e1e70da93044 590 }
Wayne Roberts 0:e1e70da93044 591
Wayne Roberts 0:e1e70da93044 592 void frf_print()
Wayne Roberts 0:e1e70da93044 593 {
Wayne Roberts 0:e1e70da93044 594 float MHz;
Wayne Roberts 0:e1e70da93044 595 #ifdef SX127x_H
Wayne Roberts 0:e1e70da93044 596 MHz = Radio::radio.get_frf_MHz();
Wayne Roberts 0:e1e70da93044 597 #else
Wayne Roberts 0:e1e70da93044 598 MHz = Radio::radio.getMHz();
Wayne Roberts 0:e1e70da93044 599 #endif
Wayne Roberts 0:e1e70da93044 600 pc.printf("%.3fMHz", MHz);
Wayne Roberts 0:e1e70da93044 601 }
Wayne Roberts 0:e1e70da93044 602
Wayne Roberts 0:e1e70da93044 603 bool frf_write(const char* valStr)
Wayne Roberts 0:e1e70da93044 604 {
Wayne Roberts 0:e1e70da93044 605 float MHz;
Wayne Roberts 0:e1e70da93044 606 sscanf(valStr, "%f", &MHz);
Wayne Roberts 0:e1e70da93044 607 #ifdef SX127x_H
Wayne Roberts 0:e1e70da93044 608 Radio::radio.set_frf_MHz(MHz);
Wayne Roberts 0:e1e70da93044 609 #else
Wayne Roberts 0:e1e70da93044 610 Radio::radio.setMHz(MHz);
Wayne Roberts 0:e1e70da93044 611 #endif
Wayne Roberts 0:e1e70da93044 612 return false;
Wayne Roberts 0:e1e70da93044 613 }
Wayne Roberts 0:e1e70da93044 614
Wayne Roberts 0:e1e70da93044 615 const value_item_t frf_item = { _ITEM_VALUE, 14, frf_print, frf_write };
Wayne Roberts 0:e1e70da93044 616
Wayne Roberts 0:e1e70da93044 617 const value_item_t Radio::tx_dbm_item = { _ITEM_VALUE, 7, Radio::tx_dbm_print, Radio::tx_dbm_write };
Wayne Roberts 0:e1e70da93044 618
Wayne Roberts 0:e1e70da93044 619 const dropdown_item_t tx_ramp_item = { _ITEM_DROPDOWN, Radio::tx_ramp_strs, Radio::tx_ramp_strs, Radio::tx_ramp_read, Radio::tx_ramp_write };
Wayne Roberts 0:e1e70da93044 620
Wayne Roberts 0:e1e70da93044 621 const button_item_t chipNum_item = { _ITEM_BUTTON, Radio::chipNum_str, NULL};
Wayne Roberts 0:e1e70da93044 622
Wayne Roberts 0:e1e70da93044 623 void botrow_print()
Wayne Roberts 0:e1e70da93044 624 {
Wayne Roberts 0:e1e70da93044 625 pc.printf("%u", botRow);
Wayne Roberts 0:e1e70da93044 626 }
Wayne Roberts 0:e1e70da93044 627
Wayne Roberts 0:e1e70da93044 628 bool botrow_write(const char* str)
Wayne Roberts 0:e1e70da93044 629 {
Wayne Roberts 0:e1e70da93044 630 unsigned n;
Wayne Roberts 0:e1e70da93044 631 sscanf(str, "%u", &n);
Wayne Roberts 0:e1e70da93044 632 botRow = n;
Wayne Roberts 0:e1e70da93044 633
Wayne Roberts 0:e1e70da93044 634 pc.printf("\e[%u;%ur", MAX_MENU_ROWS, botRow); // set scrolling region
Wayne Roberts 0:e1e70da93044 635
Wayne Roberts 0:e1e70da93044 636 return false;
Wayne Roberts 0:e1e70da93044 637 }
Wayne Roberts 0:e1e70da93044 638
Wayne Roberts 0:e1e70da93044 639 const value_item_t bottomRow_item = { _ITEM_VALUE, 4, botrow_print, botrow_write };
Wayne Roberts 0:e1e70da93044 640
Wayne Roberts 0:e1e70da93044 641 const menu_t common_menu[] = {
Wayne Roberts 0:e1e70da93044 642 { {1, 1}, NULL, &hw_reset_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 643 { {1, 15}, "packetType:", &pktType_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 644 { {1, 37}, NULL, &msgType_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 645 { {1, 50}, NULL, &chipNum_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 646 { {1, 60}, "bottomRow:", &bottomRow_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 647 { {2, 1}, NULL, &frf_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 648 { {2, 15}, "TX dBm:", &Radio::tx_dbm_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 649 { {2, 30}, "ramp us:", &tx_ramp_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 650 { {2, 45}, NULL, &clearirqs_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 651 { {2, 55}, "opmode:", &opmode_item, FLAG_MSGTYPE_ALL },
Wayne Roberts 0:e1e70da93044 652
Wayne Roberts 0:e1e70da93044 653
Wayne Roberts 0:e1e70da93044 654 { {0, 0}, NULL, NULL }
Wayne Roberts 0:e1e70da93044 655 };
Wayne Roberts 0:e1e70da93044 656
Wayne Roberts 0:e1e70da93044 657 bool
Wayne Roberts 0:e1e70da93044 658 is_menu_item_changable(uint8_t table_row, uint8_t table_col)
Wayne Roberts 0:e1e70da93044 659 {
Wayne Roberts 0:e1e70da93044 660 const menu_t* m = menu_table[table_row][table_col];
Wayne Roberts 0:e1e70da93044 661 const dropdown_item_t* di = (const dropdown_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 662
Wayne Roberts 0:e1e70da93044 663 switch (msg_type) {
Wayne Roberts 0:e1e70da93044 664 case MSG_TYPE_PACKET:
Wayne Roberts 0:e1e70da93044 665 if (m->flags & FLAG_MSGTYPE_PKT)
Wayne Roberts 0:e1e70da93044 666 break;
Wayne Roberts 0:e1e70da93044 667 else
Wayne Roberts 0:e1e70da93044 668 return false;
Wayne Roberts 0:e1e70da93044 669 case MSG_TYPE_PER:
Wayne Roberts 0:e1e70da93044 670 if (m->flags & FLAG_MSGTYPE_PER)
Wayne Roberts 0:e1e70da93044 671 break;
Wayne Roberts 0:e1e70da93044 672 else
Wayne Roberts 0:e1e70da93044 673 return false;
Wayne Roberts 0:e1e70da93044 674 case MSG_TYPE_PINGPONG:
Wayne Roberts 0:e1e70da93044 675 if (m->flags & FLAG_MSGTYPE_PING)
Wayne Roberts 0:e1e70da93044 676 break;
Wayne Roberts 0:e1e70da93044 677 else
Wayne Roberts 0:e1e70da93044 678 return false;
Wayne Roberts 0:e1e70da93044 679 }
Wayne Roberts 0:e1e70da93044 680
Wayne Roberts 0:e1e70da93044 681 if (di->itemType == _ITEM_DROPDOWN) {
Wayne Roberts 0:e1e70da93044 682 if (di->selectable_strs == NULL || di->selectable_strs[0] == NULL) {
Wayne Roberts 0:e1e70da93044 683 log_printf("NULLstrs%u,%u\r\n", table_row, table_col);
Wayne Roberts 0:e1e70da93044 684 return false;
Wayne Roberts 0:e1e70da93044 685 }
Wayne Roberts 0:e1e70da93044 686 } else if (di->itemType == _ITEM_VALUE) {
Wayne Roberts 0:e1e70da93044 687 const value_item_t* vi = (const value_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 688 if (vi->write == NULL)
Wayne Roberts 0:e1e70da93044 689 return false;
Wayne Roberts 0:e1e70da93044 690 } else if (di->itemType == _ITEM_BUTTON) {
Wayne Roberts 0:e1e70da93044 691 const button_item_t* bi = (const button_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 692 if (bi->push == NULL)
Wayne Roberts 0:e1e70da93044 693 return false;
Wayne Roberts 0:e1e70da93044 694 } else if (di->itemType == _ITEM_TOGGLE) {
Wayne Roberts 0:e1e70da93044 695 const toggle_item_t * ti = (const toggle_item_t *)m->itemPtr;
Wayne Roberts 0:e1e70da93044 696 if (ti->push == NULL)
Wayne Roberts 0:e1e70da93044 697 return false;
Wayne Roberts 0:e1e70da93044 698 }
Wayne Roberts 0:e1e70da93044 699
Wayne Roberts 0:e1e70da93044 700 return true;
Wayne Roberts 0:e1e70da93044 701 } // ..is_menu_item_changable()
Wayne Roberts 0:e1e70da93044 702
Wayne Roberts 0:e1e70da93044 703 void read_menu_item(const menu_t* m, bool selected)
Wayne Roberts 0:e1e70da93044 704 {
Wayne Roberts 0:e1e70da93044 705 uint8_t valCol;
Wayne Roberts 0:e1e70da93044 706 const dropdown_item_t* di = (const dropdown_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 707
Wayne Roberts 0:e1e70da93044 708 switch (msg_type) {
Wayne Roberts 0:e1e70da93044 709 case MSG_TYPE_PACKET:
Wayne Roberts 0:e1e70da93044 710 if (m->flags & FLAG_MSGTYPE_PKT)
Wayne Roberts 0:e1e70da93044 711 break;
Wayne Roberts 0:e1e70da93044 712 else
Wayne Roberts 0:e1e70da93044 713 return;
Wayne Roberts 0:e1e70da93044 714 case MSG_TYPE_PER:
Wayne Roberts 0:e1e70da93044 715 if (m->flags & FLAG_MSGTYPE_PER)
Wayne Roberts 0:e1e70da93044 716 break;
Wayne Roberts 0:e1e70da93044 717 else
Wayne Roberts 0:e1e70da93044 718 return;
Wayne Roberts 0:e1e70da93044 719 case MSG_TYPE_PINGPONG:
Wayne Roberts 0:e1e70da93044 720 if (m->flags & FLAG_MSGTYPE_PING)
Wayne Roberts 0:e1e70da93044 721 break;
Wayne Roberts 0:e1e70da93044 722 else
Wayne Roberts 0:e1e70da93044 723 return;
Wayne Roberts 0:e1e70da93044 724 }
Wayne Roberts 0:e1e70da93044 725
Wayne Roberts 0:e1e70da93044 726 pc.printf("\e[%u;%uf", m->pos.row, m->pos.col); // set (force) cursor to row;column
Wayne Roberts 0:e1e70da93044 727 valCol = m->pos.col;
Wayne Roberts 0:e1e70da93044 728 if (m->label) {
Wayne Roberts 0:e1e70da93044 729 pc.printf(m->label);
Wayne Roberts 0:e1e70da93044 730 valCol += strlen(m->label);
Wayne Roberts 0:e1e70da93044 731 }
Wayne Roberts 0:e1e70da93044 732 if (di->itemType == _ITEM_DROPDOWN) {
Wayne Roberts 0:e1e70da93044 733 if (di->read && di->printed_strs) {
Wayne Roberts 0:e1e70da93044 734 uint8_t ridx = di->read(false);
Wayne Roberts 0:e1e70da93044 735 if (selected)
Wayne Roberts 0:e1e70da93044 736 pc.printf("\e[7m");
Wayne Roberts 0:e1e70da93044 737 pc.printf(di->printed_strs[ridx]);
Wayne Roberts 0:e1e70da93044 738 if (selected)
Wayne Roberts 0:e1e70da93044 739 pc.printf("\e[0m");
Wayne Roberts 0:e1e70da93044 740 } else if (di->printed_strs) {
Wayne Roberts 0:e1e70da93044 741 pc.printf(di->printed_strs[0]);
Wayne Roberts 0:e1e70da93044 742 }
Wayne Roberts 0:e1e70da93044 743 } else if (di->itemType == _ITEM_VALUE) {
Wayne Roberts 0:e1e70da93044 744 const value_item_t* vi = (const value_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 745 if (vi->print) {
Wayne Roberts 0:e1e70da93044 746 for (unsigned n = 0; n < vi->width; n++)
Wayne Roberts 0:e1e70da93044 747 pc.putc(' ');
Wayne Roberts 0:e1e70da93044 748
Wayne Roberts 0:e1e70da93044 749 pc.printf("\e[%u;%uf", m->pos.row, valCol); // set (force) cursor to row;column
Wayne Roberts 0:e1e70da93044 750 if (selected)
Wayne Roberts 0:e1e70da93044 751 pc.printf("\e[7m");
Wayne Roberts 0:e1e70da93044 752 vi->print();
Wayne Roberts 0:e1e70da93044 753 if (selected)
Wayne Roberts 0:e1e70da93044 754 pc.printf("\e[0m");
Wayne Roberts 0:e1e70da93044 755 }
Wayne Roberts 0:e1e70da93044 756 } else if (di->itemType == _ITEM_BUTTON) {
Wayne Roberts 0:e1e70da93044 757 const button_item_t* bi = (const button_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 758 if (bi->label) {
Wayne Roberts 0:e1e70da93044 759 if (selected)
Wayne Roberts 0:e1e70da93044 760 pc.printf("\e[7m%s\e[0m", bi->label);
Wayne Roberts 0:e1e70da93044 761 else
Wayne Roberts 0:e1e70da93044 762 pc.printf("%s", bi->label);
Wayne Roberts 0:e1e70da93044 763 }
Wayne Roberts 0:e1e70da93044 764 } else if (di->itemType == _ITEM_TOGGLE) {
Wayne Roberts 0:e1e70da93044 765 const toggle_item_t* ti = (const toggle_item_t *)m->itemPtr;
Wayne Roberts 0:e1e70da93044 766 bool on = ti->read();
Wayne Roberts 0:e1e70da93044 767 if (ti->label1) {
Wayne Roberts 0:e1e70da93044 768 const char* const cptr = on ? ti->label1 : ti->label0;
Wayne Roberts 0:e1e70da93044 769 if (selected)
Wayne Roberts 0:e1e70da93044 770 pc.printf("\e[7m%s\e[0m", cptr);
Wayne Roberts 0:e1e70da93044 771 else
Wayne Roberts 0:e1e70da93044 772 pc.printf("%s", cptr);
Wayne Roberts 0:e1e70da93044 773 } else {
Wayne Roberts 0:e1e70da93044 774 if (on)
Wayne Roberts 0:e1e70da93044 775 pc.printf("\e[1m");
Wayne Roberts 0:e1e70da93044 776 if (selected)
Wayne Roberts 0:e1e70da93044 777 pc.printf("\e[7m");
Wayne Roberts 0:e1e70da93044 778
Wayne Roberts 0:e1e70da93044 779 pc.printf("%s", ti->label0);
Wayne Roberts 0:e1e70da93044 780
Wayne Roberts 0:e1e70da93044 781 if (selected || on)
Wayne Roberts 0:e1e70da93044 782 pc.printf("\e[0m");
Wayne Roberts 0:e1e70da93044 783 }
Wayne Roberts 0:e1e70da93044 784 }
Wayne Roberts 0:e1e70da93044 785 } // ..read_menu_item()
Wayne Roberts 0:e1e70da93044 786
Wayne Roberts 0:e1e70da93044 787 void draw_menu()
Wayne Roberts 0:e1e70da93044 788 {
Wayne Roberts 0:e1e70da93044 789 unsigned table_row;
Wayne Roberts 0:e1e70da93044 790
Wayne Roberts 0:e1e70da93044 791 for (table_row = 0; table_row < MAX_MENU_ROWS; table_row++) {
Wayne Roberts 0:e1e70da93044 792 int table_col;
Wayne Roberts 0:e1e70da93044 793 for (table_col = 0; table_col < StopMenuCols[table_row]; table_col++) {
Wayne Roberts 0:e1e70da93044 794 read_menu_item(menu_table[table_row][table_col], false);
Wayne Roberts 0:e1e70da93044 795 } // ..table column iterator
Wayne Roberts 0:e1e70da93044 796 } // ..table row iterator
Wayne Roberts 0:e1e70da93044 797
Wayne Roberts 0:e1e70da93044 798 read_menu_item(menu_table[curpos.row][curpos.tableCol], true);
Wayne Roberts 0:e1e70da93044 799
Wayne Roberts 0:e1e70da93044 800 } // ..draw_menu()
Wayne Roberts 0:e1e70da93044 801
Wayne Roberts 0:e1e70da93044 802 typedef struct {
Wayne Roberts 0:e1e70da93044 803 int row;
Wayne Roberts 0:e1e70da93044 804 int col;
Wayne Roberts 0:e1e70da93044 805 } tablexy_t;
Wayne Roberts 0:e1e70da93044 806
Wayne Roberts 0:e1e70da93044 807 void
Wayne Roberts 0:e1e70da93044 808 menu_init_(const menu_t* in, tablexy_t* tc)
Wayne Roberts 0:e1e70da93044 809 {
Wayne Roberts 0:e1e70da93044 810 unsigned n;
Wayne Roberts 0:e1e70da93044 811
Wayne Roberts 0:e1e70da93044 812 for (n = 0; in[n].pos.row > 0; n++) {
Wayne Roberts 0:e1e70da93044 813 const menu_t* m = &in[n];
Wayne Roberts 0:e1e70da93044 814 if (tc->row != m->pos.row - 1) {
Wayne Roberts 0:e1e70da93044 815 tc->row = m->pos.row - 1;
Wayne Roberts 0:e1e70da93044 816 tc->col = 0;
Wayne Roberts 0:e1e70da93044 817 } else
Wayne Roberts 0:e1e70da93044 818 tc->col++;
Wayne Roberts 0:e1e70da93044 819
Wayne Roberts 0:e1e70da93044 820 menu_table[tc->row][tc->col] = m;
Wayne Roberts 0:e1e70da93044 821 #ifdef MENU_DEBUG
Wayne Roberts 0:e1e70da93044 822 pc.printf("table:%u,%u ", tc->row, tc->col);
Wayne Roberts 0:e1e70da93044 823 pc.printf(" %d<%d? ", StopMenuCols[tc->row], tc->col);
Wayne Roberts 0:e1e70da93044 824 #endif /* MENU_DEBUG */
Wayne Roberts 0:e1e70da93044 825 if (StopMenuCols[tc->row] < tc->col)
Wayne Roberts 0:e1e70da93044 826 StopMenuCols[tc->row] = tc->col;
Wayne Roberts 0:e1e70da93044 827 #ifdef MENU_DEBUG
Wayne Roberts 0:e1e70da93044 828 pc.printf("{%u %u}", tc->row, tc->col);
Wayne Roberts 0:e1e70da93044 829 pc.printf("in:%p[%u] screen:%u,%u ", in, n, m->pos.row, m->pos.col);
Wayne Roberts 0:e1e70da93044 830 //pc.printf(" loc:%p ", &in[n].itemPtr);
Wayne Roberts 0:e1e70da93044 831 if (in[n].itemPtr) {
Wayne Roberts 0:e1e70da93044 832 const dropdown_item_t* di = (const dropdown_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 833 pc.printf(" itemPtr:%p type:%02x ", di, di->itemType);
Wayne Roberts 0:e1e70da93044 834 }
Wayne Roberts 0:e1e70da93044 835 pc.printf("stopMenuCols[%u]: %d ", tc->row, StopMenuCols[tc->row]);
Wayne Roberts 0:e1e70da93044 836 if (m->label)
Wayne Roberts 0:e1e70da93044 837 pc.printf("label:%s", m->label);
Wayne Roberts 0:e1e70da93044 838 else
Wayne Roberts 0:e1e70da93044 839 pc.printf("noLabel");
Wayne Roberts 0:e1e70da93044 840 pc.printf("\r\n");
Wayne Roberts 0:e1e70da93044 841 #endif /* MENU_DEBUG */
Wayne Roberts 0:e1e70da93044 842 }
Wayne Roberts 0:e1e70da93044 843 #ifdef MENU_DEBUG
Wayne Roberts 0:e1e70da93044 844 pc.printf("hit key:");
Wayne Roberts 0:e1e70da93044 845 wait_uart_rx(); //pc.getc();
Wayne Roberts 0:e1e70da93044 846
Wayne Roberts 0:e1e70da93044 847 #endif /* MENU_DEBUG */
Wayne Roberts 0:e1e70da93044 848
Wayne Roberts 0:e1e70da93044 849 }
Wayne Roberts 0:e1e70da93044 850
Wayne Roberts 0:e1e70da93044 851 void navigate_dropdown(uint8_t ch)
Wayne Roberts 0:e1e70da93044 852 {
Wayne Roberts 0:e1e70da93044 853 unsigned n;
Wayne Roberts 0:e1e70da93044 854 const menu_t* m = menuState.sm;
Wayne Roberts 0:e1e70da93044 855 const dropdown_item_t* di = (const dropdown_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 856
Wayne Roberts 0:e1e70da93044 857 switch (ch) {
Wayne Roberts 0:e1e70da93044 858 case 'A': // cursor UP
Wayne Roberts 0:e1e70da93044 859 if (menuState.sel_idx > 0) {
Wayne Roberts 0:e1e70da93044 860 menuState.sel_idx--;
Wayne Roberts 0:e1e70da93044 861 }
Wayne Roberts 0:e1e70da93044 862 break;
Wayne Roberts 0:e1e70da93044 863 case 'B': // cursor DOWN
Wayne Roberts 0:e1e70da93044 864 if (di->selectable_strs[menuState.sel_idx+1] != NULL)
Wayne Roberts 0:e1e70da93044 865 menuState.sel_idx++;
Wayne Roberts 0:e1e70da93044 866 break;
Wayne Roberts 0:e1e70da93044 867 } // ..switch (ch)
Wayne Roberts 0:e1e70da93044 868
Wayne Roberts 0:e1e70da93044 869 for (n = 0; di->selectable_strs[n] != NULL; n++) {
Wayne Roberts 0:e1e70da93044 870 pc.printf("\e[%u;%uf", m->pos.row+n, menuState.dropdown_col);
Wayne Roberts 0:e1e70da93044 871 if (n == menuState.sel_idx)
Wayne Roberts 0:e1e70da93044 872 pc.printf("\e[7m");
Wayne Roberts 0:e1e70da93044 873 pc.printf(di->selectable_strs[n]);
Wayne Roberts 0:e1e70da93044 874 if (n == menuState.sel_idx)
Wayne Roberts 0:e1e70da93044 875 pc.printf("\e[0m");
Wayne Roberts 0:e1e70da93044 876 }
Wayne Roberts 0:e1e70da93044 877 pc.printf("\e[%u;%uf", m->pos.row + menuState.sel_idx, menuState.dropdown_col + strlen(di->selectable_strs[menuState.sel_idx]));
Wayne Roberts 0:e1e70da93044 878 }
Wayne Roberts 0:e1e70da93044 879
Wayne Roberts 0:e1e70da93044 880 bool is_item_selectable(const menu_t* m)
Wayne Roberts 0:e1e70da93044 881 {
Wayne Roberts 0:e1e70da93044 882 const dropdown_item_t* di = (const dropdown_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 883
Wayne Roberts 0:e1e70da93044 884 if (di->itemType == _ITEM_BUTTON) {
Wayne Roberts 0:e1e70da93044 885 const button_item_t* bi = (const button_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 886 if (bi->push == NULL)
Wayne Roberts 0:e1e70da93044 887 return false;
Wayne Roberts 0:e1e70da93044 888 } else if (di->itemType == _ITEM_TOGGLE) {
Wayne Roberts 0:e1e70da93044 889 const toggle_item_t* ti = (const toggle_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 890 if (ti->push == NULL)
Wayne Roberts 0:e1e70da93044 891 return false;
Wayne Roberts 0:e1e70da93044 892 }
Wayne Roberts 0:e1e70da93044 893
Wayne Roberts 0:e1e70da93044 894 return true;
Wayne Roberts 0:e1e70da93044 895 }
Wayne Roberts 0:e1e70da93044 896
Wayne Roberts 0:e1e70da93044 897 void navigate_menu(uint8_t ch)
Wayne Roberts 0:e1e70da93044 898 {
Wayne Roberts 0:e1e70da93044 899 read_menu_item(menu_table[curpos.row][curpos.tableCol], false);
Wayne Roberts 0:e1e70da93044 900
Wayne Roberts 0:e1e70da93044 901 switch (ch) {
Wayne Roberts 0:e1e70da93044 902 case 'A': // cursor UP
Wayne Roberts 0:e1e70da93044 903 if (curpos.row == 0)
Wayne Roberts 0:e1e70da93044 904 break;
Wayne Roberts 0:e1e70da93044 905
Wayne Roberts 0:e1e70da93044 906 { // find previous row up with column
Wayne Roberts 0:e1e70da93044 907 int8_t row;
Wayne Roberts 0:e1e70da93044 908 for (row = curpos.row - 1; row >= 0; row--) {
Wayne Roberts 0:e1e70da93044 909 if (StopMenuCols[row] > -1) {
Wayne Roberts 0:e1e70da93044 910 curpos.row = row;
Wayne Roberts 0:e1e70da93044 911 break;
Wayne Roberts 0:e1e70da93044 912 }
Wayne Roberts 0:e1e70da93044 913 }
Wayne Roberts 0:e1e70da93044 914 if (row == 0 && StopMenuCols[0] < 0)
Wayne Roberts 0:e1e70da93044 915 break; // nothing found
Wayne Roberts 0:e1e70da93044 916 }
Wayne Roberts 0:e1e70da93044 917
Wayne Roberts 0:e1e70da93044 918 if (curpos.tableCol >= StopMenuCols[curpos.row]) {
Wayne Roberts 0:e1e70da93044 919 curpos.tableCol = StopMenuCols[curpos.row]-1;
Wayne Roberts 0:e1e70da93044 920 }
Wayne Roberts 0:e1e70da93044 921
Wayne Roberts 0:e1e70da93044 922 break;
Wayne Roberts 0:e1e70da93044 923 case 'B': // cursor DOWN
Wayne Roberts 0:e1e70da93044 924 if (curpos.row >= MAX_MENU_ROWS)
Wayne Roberts 0:e1e70da93044 925 break;
Wayne Roberts 0:e1e70da93044 926
Wayne Roberts 0:e1e70da93044 927 { // find next row down with column
Wayne Roberts 0:e1e70da93044 928 uint8_t row;
Wayne Roberts 0:e1e70da93044 929 for (row = curpos.row + 1; row < MAX_MENU_ROWS; row++) {
Wayne Roberts 0:e1e70da93044 930 if (StopMenuCols[row] != -1) {
Wayne Roberts 0:e1e70da93044 931 curpos.row = row;
Wayne Roberts 0:e1e70da93044 932 break;
Wayne Roberts 0:e1e70da93044 933 }
Wayne Roberts 0:e1e70da93044 934 }
Wayne Roberts 0:e1e70da93044 935 if (row == MAX_MENU_ROWS-1 && StopMenuCols[row] == -1)
Wayne Roberts 0:e1e70da93044 936 break; // nothing found
Wayne Roberts 0:e1e70da93044 937 }
Wayne Roberts 0:e1e70da93044 938
Wayne Roberts 0:e1e70da93044 939 if (curpos.tableCol >= StopMenuCols[curpos.row]) {
Wayne Roberts 0:e1e70da93044 940 curpos.tableCol = StopMenuCols[curpos.row]-1;
Wayne Roberts 0:e1e70da93044 941 }
Wayne Roberts 0:e1e70da93044 942
Wayne Roberts 0:e1e70da93044 943
Wayne Roberts 0:e1e70da93044 944 break;
Wayne Roberts 0:e1e70da93044 945 case 'C': // cursor LEFT
Wayne Roberts 0:e1e70da93044 946 if (curpos.tableCol >= StopMenuCols[curpos.row]-1)
Wayne Roberts 0:e1e70da93044 947 break;
Wayne Roberts 0:e1e70da93044 948
Wayne Roberts 0:e1e70da93044 949 { // find next row left with editable
Wayne Roberts 0:e1e70da93044 950 uint8_t tcol;
Wayne Roberts 0:e1e70da93044 951 for (tcol = curpos.tableCol + 1; tcol < StopMenuCols[curpos.row]; tcol++) {
Wayne Roberts 0:e1e70da93044 952 if (is_menu_item_changable(curpos.row, tcol)) {
Wayne Roberts 0:e1e70da93044 953 curpos.tableCol = tcol;
Wayne Roberts 0:e1e70da93044 954 break;
Wayne Roberts 0:e1e70da93044 955 }
Wayne Roberts 0:e1e70da93044 956 }
Wayne Roberts 0:e1e70da93044 957 }
Wayne Roberts 0:e1e70da93044 958
Wayne Roberts 0:e1e70da93044 959 break;
Wayne Roberts 0:e1e70da93044 960 case 'D': // cursor RIGHT
Wayne Roberts 0:e1e70da93044 961 if (curpos.tableCol == 0)
Wayne Roberts 0:e1e70da93044 962 break;
Wayne Roberts 0:e1e70da93044 963
Wayne Roberts 0:e1e70da93044 964 {
Wayne Roberts 0:e1e70da93044 965 int8_t tcol;
Wayne Roberts 0:e1e70da93044 966 for (tcol = curpos.tableCol - 1; tcol >= 0; tcol--) {
Wayne Roberts 0:e1e70da93044 967 if (is_menu_item_changable(curpos.row, tcol)) {
Wayne Roberts 0:e1e70da93044 968 curpos.tableCol = tcol;
Wayne Roberts 0:e1e70da93044 969 break;
Wayne Roberts 0:e1e70da93044 970 }
Wayne Roberts 0:e1e70da93044 971 }
Wayne Roberts 0:e1e70da93044 972 }
Wayne Roberts 0:e1e70da93044 973
Wayne Roberts 0:e1e70da93044 974 break;
Wayne Roberts 0:e1e70da93044 975 default:
Wayne Roberts 0:e1e70da93044 976 //pc.printf("unhancled-csi:%02x\eE", ch);
Wayne Roberts 0:e1e70da93044 977 break;
Wayne Roberts 0:e1e70da93044 978 } // ..switch (ch)
Wayne Roberts 0:e1e70da93044 979
Wayne Roberts 0:e1e70da93044 980 if (!is_item_selectable(menu_table[curpos.row][curpos.tableCol])) {
Wayne Roberts 0:e1e70da93044 981 int c;
Wayne Roberts 0:e1e70da93044 982 for (c = 0; c < StopMenuCols[curpos.row]; c++) {
Wayne Roberts 0:e1e70da93044 983 if (is_item_selectable(menu_table[curpos.row][c])) {
Wayne Roberts 0:e1e70da93044 984 curpos.tableCol = c;
Wayne Roberts 0:e1e70da93044 985 break;
Wayne Roberts 0:e1e70da93044 986 }
Wayne Roberts 0:e1e70da93044 987 }
Wayne Roberts 0:e1e70da93044 988 if (c == StopMenuCols[curpos.row])
Wayne Roberts 0:e1e70da93044 989 return;
Wayne Roberts 0:e1e70da93044 990 }
Wayne Roberts 0:e1e70da93044 991
Wayne Roberts 0:e1e70da93044 992 #ifdef MENU_DEBUG
Wayne Roberts 0:e1e70da93044 993 log_printf("table:%u,%u screen:%u,%u \r\n", curpos.row, curpos.tableCol,
Wayne Roberts 0:e1e70da93044 994 menu_table[curpos.row][curpos.tableCol]->pos.row,
Wayne Roberts 0:e1e70da93044 995 menu_table[curpos.row][curpos.tableCol]->pos.col
Wayne Roberts 0:e1e70da93044 996 );
Wayne Roberts 0:e1e70da93044 997 #endif /* MENU_DEBUG */
Wayne Roberts 0:e1e70da93044 998
Wayne Roberts 0:e1e70da93044 999 read_menu_item(menu_table[curpos.row][curpos.tableCol], true);
Wayne Roberts 0:e1e70da93044 1000 } // ..navigate_menu
Wayne Roberts 0:e1e70da93044 1001
Wayne Roberts 0:e1e70da93044 1002 void commit_menu_item_change()
Wayne Roberts 0:e1e70da93044 1003 {
Wayne Roberts 0:e1e70da93044 1004 const menu_t* m = menu_table[curpos.row][curpos.tableCol];
Wayne Roberts 0:e1e70da93044 1005 const dropdown_item_t* di = (const dropdown_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 1006
Wayne Roberts 0:e1e70da93044 1007 if (di->itemType == _ITEM_DROPDOWN) {
Wayne Roberts 0:e1e70da93044 1008 menuState.mode = di->write(menuState.sel_idx);
Wayne Roberts 0:e1e70da93044 1009
Wayne Roberts 0:e1e70da93044 1010 pc.printf("\e[%u;%uf", m->pos.row, m->pos.col-2);
Wayne Roberts 0:e1e70da93044 1011 } else if (di->itemType == _ITEM_VALUE) {
Wayne Roberts 0:e1e70da93044 1012 const value_item_t* vi = (const value_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 1013 /* commit value entry */
Wayne Roberts 0:e1e70da93044 1014 if (vi->write) {
Wayne Roberts 0:e1e70da93044 1015 if (vi->write(entry_buf))
Wayne Roberts 0:e1e70da93044 1016 menuState.mode = MENUMODE_REDRAW;
Wayne Roberts 0:e1e70da93044 1017 else
Wayne Roberts 0:e1e70da93044 1018 menuState.mode = MENUMODE_NONE;
Wayne Roberts 0:e1e70da93044 1019 } else
Wayne Roberts 0:e1e70da93044 1020 menuState.mode = MENUMODE_NONE;
Wayne Roberts 0:e1e70da93044 1021
Wayne Roberts 0:e1e70da93044 1022 if (menuState.mode == MENUMODE_NONE) {
Wayne Roberts 0:e1e70da93044 1023 read_menu_item(menu_table[curpos.row][curpos.tableCol], true);
Wayne Roberts 0:e1e70da93044 1024 }
Wayne Roberts 0:e1e70da93044 1025 }
Wayne Roberts 0:e1e70da93044 1026 } // ..commit_menu_item_change()
Wayne Roberts 0:e1e70da93044 1027
Wayne Roberts 0:e1e70da93044 1028 void refresh_item_in_table(const void* item)
Wayne Roberts 0:e1e70da93044 1029 {
Wayne Roberts 0:e1e70da93044 1030 unsigned table_row;
Wayne Roberts 0:e1e70da93044 1031
Wayne Roberts 0:e1e70da93044 1032 if (item == NULL)
Wayne Roberts 0:e1e70da93044 1033 return;
Wayne Roberts 0:e1e70da93044 1034
Wayne Roberts 0:e1e70da93044 1035 for (table_row = 0; table_row < MAX_MENU_ROWS; table_row++) {
Wayne Roberts 0:e1e70da93044 1036 int table_col;
Wayne Roberts 0:e1e70da93044 1037 for (table_col = 0; table_col < StopMenuCols[table_row]; table_col++) {
Wayne Roberts 0:e1e70da93044 1038 //log_printf("%u %u %p\r\n", table_row, table_col, menu_table[table_row][table_col]->itemPtr);
Wayne Roberts 0:e1e70da93044 1039 if (item == menu_table[table_row][table_col]->itemPtr) {
Wayne Roberts 0:e1e70da93044 1040 read_menu_item(menu_table[table_row][table_col], false);
Wayne Roberts 0:e1e70da93044 1041 return;
Wayne Roberts 0:e1e70da93044 1042 }
Wayne Roberts 0:e1e70da93044 1043 }
Wayne Roberts 0:e1e70da93044 1044 }
Wayne Roberts 0:e1e70da93044 1045 }
Wayne Roberts 0:e1e70da93044 1046
Wayne Roberts 0:e1e70da93044 1047 void
Wayne Roberts 0:e1e70da93044 1048 start_value_entry(const menu_t* m)
Wayne Roberts 0:e1e70da93044 1049 {
Wayne Roberts 0:e1e70da93044 1050 const value_item_t* vi = (const value_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 1051 uint8_t col = m->pos.col;
Wayne Roberts 0:e1e70da93044 1052
Wayne Roberts 0:e1e70da93044 1053 if (m->label)
Wayne Roberts 0:e1e70da93044 1054 col += strlen(m->label);
Wayne Roberts 0:e1e70da93044 1055
Wayne Roberts 0:e1e70da93044 1056 pc.printf("\e[%u;%uf", m->pos.row, col);
Wayne Roberts 0:e1e70da93044 1057 for (unsigned i = 0; i < vi->width; i++)
Wayne Roberts 0:e1e70da93044 1058 pc.putc(' '); // clear displayed value for user entry
Wayne Roberts 0:e1e70da93044 1059
Wayne Roberts 0:e1e70da93044 1060 pc.printf("\e[%u;%uf", m->pos.row, col);
Wayne Roberts 0:e1e70da93044 1061 menuState.mode = MENUMODE_ENTRY;
Wayne Roberts 0:e1e70da93044 1062 entry_buf_idx = 0;
Wayne Roberts 0:e1e70da93044 1063 }
Wayne Roberts 0:e1e70da93044 1064
Wayne Roberts 0:e1e70da93044 1065 void start_menu_item_change()
Wayne Roberts 0:e1e70da93044 1066 {
Wayne Roberts 0:e1e70da93044 1067 const menu_t* m = menu_table[curpos.row][curpos.tableCol];
Wayne Roberts 0:e1e70da93044 1068 const dropdown_item_t* di = (const dropdown_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 1069 bool checkRefresh = false;
Wayne Roberts 0:e1e70da93044 1070
Wayne Roberts 0:e1e70da93044 1071 if (di->itemType == _ITEM_DROPDOWN && di->selectable_strs) {
Wayne Roberts 0:e1e70da93044 1072 menuState.dropdown_col = m->pos.col;
Wayne Roberts 0:e1e70da93044 1073 unsigned n, sidx = 0;
Wayne Roberts 0:e1e70da93044 1074 /* start dropdown */
Wayne Roberts 0:e1e70da93044 1075 if (di->read)
Wayne Roberts 0:e1e70da93044 1076 sidx = di->read(true);
Wayne Roberts 0:e1e70da93044 1077
Wayne Roberts 0:e1e70da93044 1078 if (m->label)
Wayne Roberts 0:e1e70da93044 1079 menuState.dropdown_col += strlen(m->label);
Wayne Roberts 0:e1e70da93044 1080
Wayne Roberts 0:e1e70da93044 1081 for (n = 0; di->selectable_strs[n] != NULL; n++) {
Wayne Roberts 0:e1e70da93044 1082 uint8_t col = menuState.dropdown_col;
Wayne Roberts 0:e1e70da93044 1083 bool leftPad = false;
Wayne Roberts 0:e1e70da93044 1084 if (col > 3 && n > 0) { // dropdown left side padding
Wayne Roberts 0:e1e70da93044 1085 col -= 2;
Wayne Roberts 0:e1e70da93044 1086 leftPad = true;
Wayne Roberts 0:e1e70da93044 1087 }
Wayne Roberts 0:e1e70da93044 1088 pc.printf("\e[%u;%uf", m->pos.row+n, col);
Wayne Roberts 0:e1e70da93044 1089 if (leftPad ) {
Wayne Roberts 0:e1e70da93044 1090 pc.putc(' ');
Wayne Roberts 0:e1e70da93044 1091 pc.putc(' ');
Wayne Roberts 0:e1e70da93044 1092 }
Wayne Roberts 0:e1e70da93044 1093 if (n == sidx)
Wayne Roberts 0:e1e70da93044 1094 pc.printf("\e[7m");
Wayne Roberts 0:e1e70da93044 1095 pc.printf(di->selectable_strs[n]);
Wayne Roberts 0:e1e70da93044 1096 if (n == sidx)
Wayne Roberts 0:e1e70da93044 1097 pc.printf("\e[0m");
Wayne Roberts 0:e1e70da93044 1098 pc.putc(' '); // right side padding
Wayne Roberts 0:e1e70da93044 1099 pc.putc(' ');
Wayne Roberts 0:e1e70da93044 1100 }
Wayne Roberts 0:e1e70da93044 1101 pc.printf("\e[%u;%uf", m->pos.row, menuState.dropdown_col-2);
Wayne Roberts 0:e1e70da93044 1102
Wayne Roberts 0:e1e70da93044 1103 menuState.mode = MENUMODE_DROPDOWN;
Wayne Roberts 0:e1e70da93044 1104 menuState.sel_idx = sidx;
Wayne Roberts 0:e1e70da93044 1105 menuState.sm = m;
Wayne Roberts 0:e1e70da93044 1106 } else if (di->itemType == _ITEM_VALUE) {
Wayne Roberts 0:e1e70da93044 1107 /* start value entry */
Wayne Roberts 0:e1e70da93044 1108 start_value_entry(m);
Wayne Roberts 0:e1e70da93044 1109 } else if (di->itemType == _ITEM_BUTTON) {
Wayne Roberts 0:e1e70da93044 1110 const button_item_t* bi = (const button_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 1111 if (bi->push) {
Wayne Roberts 0:e1e70da93044 1112 bi->push();
Wayne Roberts 0:e1e70da93044 1113 checkRefresh = true;
Wayne Roberts 0:e1e70da93044 1114 }
Wayne Roberts 0:e1e70da93044 1115 } else if (di->itemType == _ITEM_TOGGLE) {
Wayne Roberts 0:e1e70da93044 1116 const toggle_item_t* ti = (const toggle_item_t*)m->itemPtr;
Wayne Roberts 0:e1e70da93044 1117 if (ti->push) {
Wayne Roberts 0:e1e70da93044 1118 bool on = ti->push();
Wayne Roberts 0:e1e70da93044 1119 uint8_t col = m->pos.col;
Wayne Roberts 0:e1e70da93044 1120
Wayne Roberts 0:e1e70da93044 1121 if (m->label)
Wayne Roberts 0:e1e70da93044 1122 col += strlen(m->label);
Wayne Roberts 0:e1e70da93044 1123
Wayne Roberts 0:e1e70da93044 1124 pc.printf("\e[%u;%uf", m->pos.row, col);
Wayne Roberts 0:e1e70da93044 1125 if (ti->label1) {
Wayne Roberts 0:e1e70da93044 1126 pc.printf("\e[7m%s\e[0m", on ? ti->label1 : ti->label0);
Wayne Roberts 0:e1e70da93044 1127 } else {
Wayne Roberts 0:e1e70da93044 1128 if (on)
Wayne Roberts 0:e1e70da93044 1129 pc.printf("\e[1;7m%s\e[0m", ti->label0);
Wayne Roberts 0:e1e70da93044 1130 else
Wayne Roberts 0:e1e70da93044 1131 pc.printf("\e[7m%s\e[0m", ti->label0);
Wayne Roberts 0:e1e70da93044 1132 }
Wayne Roberts 0:e1e70da93044 1133 checkRefresh = true;
Wayne Roberts 0:e1e70da93044 1134 }
Wayne Roberts 0:e1e70da93044 1135 }
Wayne Roberts 0:e1e70da93044 1136
Wayne Roberts 0:e1e70da93044 1137 if (checkRefresh) {
Wayne Roberts 0:e1e70da93044 1138 if (m->refreshReadItem) {
Wayne Roberts 0:e1e70da93044 1139 refresh_item_in_table(m->refreshReadItem); // read associated
Wayne Roberts 0:e1e70da93044 1140 read_menu_item(m, true); // restore cursor
Wayne Roberts 0:e1e70da93044 1141 }
Wayne Roberts 0:e1e70da93044 1142 }
Wayne Roberts 0:e1e70da93044 1143 } // ..start_menu_item_change()
Wayne Roberts 0:e1e70da93044 1144
Wayne Roberts 0:e1e70da93044 1145 void full_menu_init()
Wayne Roberts 0:e1e70da93044 1146 {
Wayne Roberts 0:e1e70da93044 1147 unsigned n;
Wayne Roberts 0:e1e70da93044 1148 const menu_t *m;
Wayne Roberts 0:e1e70da93044 1149 tablexy_t txy;
Wayne Roberts 0:e1e70da93044 1150
Wayne Roberts 0:e1e70da93044 1151 txy.row = INT_MAX;
Wayne Roberts 0:e1e70da93044 1152 txy.col = 0;
Wayne Roberts 0:e1e70da93044 1153
Wayne Roberts 0:e1e70da93044 1154 for (n = 0; n < MAX_MENU_ROWS; n++) {
Wayne Roberts 0:e1e70da93044 1155 StopMenuCols[n] = -1;
Wayne Roberts 0:e1e70da93044 1156 }
Wayne Roberts 0:e1e70da93044 1157
Wayne Roberts 0:e1e70da93044 1158 menu_init_(common_menu, &txy);
Wayne Roberts 0:e1e70da93044 1159
Wayne Roberts 0:e1e70da93044 1160 menu_init_(Radio::common_menu, &txy);
Wayne Roberts 0:e1e70da93044 1161
Wayne Roberts 0:e1e70da93044 1162 m = Radio::get_modem_menu();
Wayne Roberts 0:e1e70da93044 1163 if (m == NULL) {
Wayne Roberts 0:e1e70da93044 1164 log_printf("NULL-modemMenu\r\n");
Wayne Roberts 0:e1e70da93044 1165 for (;;) asm("nop");
Wayne Roberts 0:e1e70da93044 1166 }
Wayne Roberts 0:e1e70da93044 1167 #ifdef MENU_DEBUG
Wayne Roberts 0:e1e70da93044 1168 pc.printf("modemmenuInit\r\n");
Wayne Roberts 0:e1e70da93044 1169 #endif
Wayne Roberts 0:e1e70da93044 1170 menu_init_(m, &txy);
Wayne Roberts 0:e1e70da93044 1171
Wayne Roberts 0:e1e70da93044 1172 m = Radio::get_modem_sub_menu();
Wayne Roberts 0:e1e70da93044 1173 if (m) {
Wayne Roberts 0:e1e70da93044 1174 #ifdef MENU_DEBUG
Wayne Roberts 0:e1e70da93044 1175 pc.printf("modemsubmenuInit\r\n");
Wayne Roberts 0:e1e70da93044 1176 #endif
Wayne Roberts 0:e1e70da93044 1177 menu_init_(m, &txy);
Wayne Roberts 0:e1e70da93044 1178 }
Wayne Roberts 0:e1e70da93044 1179 #ifdef MENU_DEBUG
Wayne Roberts 0:e1e70da93044 1180 else
Wayne Roberts 0:e1e70da93044 1181 pc.printf("no-modemsubmenu\r\n");
Wayne Roberts 0:e1e70da93044 1182 #endif
Wayne Roberts 0:e1e70da93044 1183
Wayne Roberts 0:e1e70da93044 1184 #ifdef PHOTOS_PIN
Wayne Roberts 0:e1e70da93044 1185 menu_init_(photos_menu, &txy);
Wayne Roberts 0:e1e70da93044 1186 #endif /* PHOTOS_PIN */
Wayne Roberts 0:e1e70da93044 1187 menu_init_(lis12dh12_menu, &txy);
Wayne Roberts 0:e1e70da93044 1188 menu_init_(lps22hh_menu, &txy);
Wayne Roberts 0:e1e70da93044 1189
Wayne Roberts 0:e1e70da93044 1190 m = get_msg_menu();
Wayne Roberts 0:e1e70da93044 1191 if (m == NULL) {
Wayne Roberts 0:e1e70da93044 1192 log_printf("NULL-msgMenu\r\n");
Wayne Roberts 0:e1e70da93044 1193 for (;;) asm("nop");
Wayne Roberts 0:e1e70da93044 1194 }
Wayne Roberts 0:e1e70da93044 1195 menu_init_(m, &txy);
Wayne Roberts 0:e1e70da93044 1196
Wayne Roberts 0:e1e70da93044 1197 for (n = 0; n < MAX_MENU_ROWS; n++) {
Wayne Roberts 0:e1e70da93044 1198 if (StopMenuCols[n] != -1)
Wayne Roberts 0:e1e70da93044 1199 StopMenuCols[n]++;
Wayne Roberts 0:e1e70da93044 1200 }
Wayne Roberts 0:e1e70da93044 1201 }
Wayne Roberts 0:e1e70da93044 1202
Wayne Roberts 0:e1e70da93044 1203 bool ishexchar(char ch)
Wayne Roberts 0:e1e70da93044 1204 {
Wayne Roberts 0:e1e70da93044 1205 if (((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) || (ch >= '0' && ch <= '9'))
Wayne Roberts 0:e1e70da93044 1206 return true;
Wayne Roberts 0:e1e70da93044 1207 else
Wayne Roberts 0:e1e70da93044 1208 return false;
Wayne Roberts 0:e1e70da93044 1209 }
Wayne Roberts 0:e1e70da93044 1210
Wayne Roberts 0:e1e70da93044 1211 enum _urx_ {
Wayne Roberts 0:e1e70da93044 1212 URX_STATE_NONE = 0,
Wayne Roberts 0:e1e70da93044 1213 URX_STATE_ESCAPE,
Wayne Roberts 0:e1e70da93044 1214 URX_STATE_CSI,
Wayne Roberts 0:e1e70da93044 1215 } uart_rx_state;
Wayne Roberts 0:e1e70da93044 1216
Wayne Roberts 0:e1e70da93044 1217 Timeout uartRxTimeout;
Wayne Roberts 0:e1e70da93044 1218
Wayne Roberts 0:e1e70da93044 1219 void uart_rx_timeout()
Wayne Roberts 0:e1e70da93044 1220 {
Wayne Roberts 0:e1e70da93044 1221 /* escape by itself: abort change on item */
Wayne Roberts 0:e1e70da93044 1222 menuState.mode = MENUMODE_REDRAW;
Wayne Roberts 0:e1e70da93044 1223
Wayne Roberts 0:e1e70da93044 1224 uart_rx_state = URX_STATE_NONE;
Wayne Roberts 0:e1e70da93044 1225 }
Wayne Roberts 0:e1e70da93044 1226
Wayne Roberts 0:e1e70da93044 1227 void serial_callback(char ch)
Wayne Roberts 0:e1e70da93044 1228 {
Wayne Roberts 0:e1e70da93044 1229 switch (uart_rx_state) {
Wayne Roberts 0:e1e70da93044 1230 case URX_STATE_NONE:
Wayne Roberts 0:e1e70da93044 1231 if (ch == 0x1b) {
Wayne Roberts 0:e1e70da93044 1232 if (menuState.mode == MENUMODE_ENTRY) {
Wayne Roberts 0:e1e70da93044 1233 /* abort entry mode */
Wayne Roberts 0:e1e70da93044 1234 menuState.mode = MENUMODE_NONE;
Wayne Roberts 0:e1e70da93044 1235 read_menu_item(menu_table[curpos.row][curpos.tableCol], true);
Wayne Roberts 0:e1e70da93044 1236 } else {
Wayne Roberts 0:e1e70da93044 1237 uart_rx_state = URX_STATE_ESCAPE;
Wayne Roberts 0:e1e70da93044 1238 if (menuState.mode != MENUMODE_NONE) {
Wayne Roberts 0:e1e70da93044 1239 /* is this escape by itself, user wants to abort? */
Wayne Roberts 0:e1e70da93044 1240 uartRxTimeout.attach(uart_rx_timeout, 0.03);
Wayne Roberts 0:e1e70da93044 1241 }
Wayne Roberts 0:e1e70da93044 1242 }
Wayne Roberts 0:e1e70da93044 1243 } else if (ch == 2) { // ctrl-B
Wayne Roberts 0:e1e70da93044 1244 log_printf("--------------\r\n");
Wayne Roberts 0:e1e70da93044 1245 } else if (ch == '\r') {
Wayne Roberts 0:e1e70da93044 1246 if (menuState.mode == MENUMODE_NONE) {
Wayne Roberts 0:e1e70da93044 1247 start_menu_item_change();
Wayne Roberts 0:e1e70da93044 1248 } else {
Wayne Roberts 0:e1e70da93044 1249 entry_buf[entry_buf_idx] = 0;
Wayne Roberts 0:e1e70da93044 1250 commit_menu_item_change();
Wayne Roberts 0:e1e70da93044 1251 }
Wayne Roberts 0:e1e70da93044 1252 } else if (menuState.mode == MENUMODE_ENTRY) {
Wayne Roberts 0:e1e70da93044 1253 if (ch == 8) {
Wayne Roberts 0:e1e70da93044 1254 if (entry_buf_idx > 0) {
Wayne Roberts 0:e1e70da93044 1255 pc.putc(8);
Wayne Roberts 0:e1e70da93044 1256 pc.putc(' ');
Wayne Roberts 0:e1e70da93044 1257 pc.putc(8);
Wayne Roberts 0:e1e70da93044 1258 entry_buf_idx--;
Wayne Roberts 0:e1e70da93044 1259 }
Wayne Roberts 0:e1e70da93044 1260 } else if (ch == 3) { // ctrl-C
Wayne Roberts 0:e1e70da93044 1261 menuState.mode = MENUMODE_NONE;
Wayne Roberts 0:e1e70da93044 1262 } else if (entry_buf_idx < sizeof(entry_buf)) {
Wayne Roberts 0:e1e70da93044 1263 entry_buf[entry_buf_idx++] = ch;
Wayne Roberts 0:e1e70da93044 1264 pc.putc(ch);
Wayne Roberts 0:e1e70da93044 1265 }
Wayne Roberts 0:e1e70da93044 1266 } else if (menuState.mode == MENUMODE_NONE) {
Wayne Roberts 0:e1e70da93044 1267 if (ishexchar(ch) || ch == '-') { // characters which start entry
Wayne Roberts 0:e1e70da93044 1268 const value_item_t* vi = (const value_item_t*)menu_table[curpos.row][curpos.tableCol]->itemPtr;
Wayne Roberts 0:e1e70da93044 1269 if (vi->itemType == _ITEM_VALUE) {
Wayne Roberts 0:e1e70da93044 1270 start_value_entry(menu_table[curpos.row][curpos.tableCol]);
Wayne Roberts 0:e1e70da93044 1271 entry_buf[entry_buf_idx++] = ch;
Wayne Roberts 0:e1e70da93044 1272 pc.putc(ch);
Wayne Roberts 0:e1e70da93044 1273 }
Wayne Roberts 0:e1e70da93044 1274 } else if (ch == 'r') {
Wayne Roberts 0:e1e70da93044 1275 menuState.mode = MENUMODE_REDRAW;
Wayne Roberts 0:e1e70da93044 1276 } else if (ch == '.') {
Wayne Roberts 0:e1e70da93044 1277 Radio::test();
Wayne Roberts 0:e1e70da93044 1278 }
Wayne Roberts 0:e1e70da93044 1279
Wayne Roberts 0:e1e70da93044 1280 }
Wayne Roberts 0:e1e70da93044 1281 break;
Wayne Roberts 0:e1e70da93044 1282 case URX_STATE_ESCAPE:
Wayne Roberts 0:e1e70da93044 1283 uartRxTimeout.detach();
Wayne Roberts 0:e1e70da93044 1284 if (ch == '[')
Wayne Roberts 0:e1e70da93044 1285 uart_rx_state = URX_STATE_CSI;
Wayne Roberts 0:e1e70da93044 1286 else {
Wayne Roberts 0:e1e70da93044 1287 #ifdef MENU_DEBUG
Wayne Roberts 0:e1e70da93044 1288 log_printf("unhancled-esc:%02x\r\n", ch);
Wayne Roberts 0:e1e70da93044 1289 #endif /* MENU_DEBUG */
Wayne Roberts 0:e1e70da93044 1290 uart_rx_state = URX_STATE_NONE;
Wayne Roberts 0:e1e70da93044 1291 }
Wayne Roberts 0:e1e70da93044 1292 break;
Wayne Roberts 0:e1e70da93044 1293 case URX_STATE_CSI:
Wayne Roberts 0:e1e70da93044 1294 if (menuState.mode == MENUMODE_NONE)
Wayne Roberts 0:e1e70da93044 1295 navigate_menu(ch);
Wayne Roberts 0:e1e70da93044 1296 else if (menuState.mode == MENUMODE_DROPDOWN)
Wayne Roberts 0:e1e70da93044 1297 navigate_dropdown(ch);
Wayne Roberts 0:e1e70da93044 1298
Wayne Roberts 0:e1e70da93044 1299 uart_rx_state = URX_STATE_NONE;
Wayne Roberts 0:e1e70da93044 1300 //pc.printf("\e[18;1f"); // set (force) cursor to row;column
Wayne Roberts 0:e1e70da93044 1301 break;
Wayne Roberts 0:e1e70da93044 1302 } // ..switch (uart_rx_state)
Wayne Roberts 0:e1e70da93044 1303 }
Wayne Roberts 0:e1e70da93044 1304
Wayne Roberts 0:e1e70da93044 1305 void ev_uart_rx()
Wayne Roberts 0:e1e70da93044 1306 {
Wayne Roberts 0:e1e70da93044 1307 log_printf("ev_uart_rx %u %u\r\n", uart_rx_buf_in, uart_rx_buf_out);
Wayne Roberts 0:e1e70da93044 1308 while (uart_rx_buf_in != uart_rx_buf_out) {
Wayne Roberts 0:e1e70da93044 1309 log_printf("X ev_uart_rx %u %u\r\n", uart_rx_buf_in, uart_rx_buf_out);
Wayne Roberts 0:e1e70da93044 1310 serial_callback(uart_rx_buf[uart_rx_buf_out++]);
Wayne Roberts 0:e1e70da93044 1311 if (uart_rx_buf_out == UART_RX_BUF_LEN)
Wayne Roberts 0:e1e70da93044 1312 uart_rx_buf_out = 0;
Wayne Roberts 0:e1e70da93044 1313 }
Wayne Roberts 0:e1e70da93044 1314 }
Wayne Roberts 0:e1e70da93044 1315
Wayne Roberts 0:e1e70da93044 1316 //volatile unsigned rxCnt = 0;
Wayne Roberts 0:e1e70da93044 1317 void rx_isr()
Wayne Roberts 0:e1e70da93044 1318 {
Wayne Roberts 0:e1e70da93044 1319 //rxCnt++;
Wayne Roberts 0:e1e70da93044 1320 uart_rx_buf[uart_rx_buf_in++] = pc.getc();
Wayne Roberts 0:e1e70da93044 1321 if (uart_rx_buf_in == UART_RX_BUF_LEN)
Wayne Roberts 0:e1e70da93044 1322 uart_rx_buf_in = 0;
Wayne Roberts 0:e1e70da93044 1323
Wayne Roberts 0:e1e70da93044 1324 //queue.call(ev_uart_rx);
Wayne Roberts 0:e1e70da93044 1325 }
Wayne Roberts 0:e1e70da93044 1326
Wayne Roberts 0:e1e70da93044 1327
Wayne Roberts 0:e1e70da93044 1328 void txDone()
Wayne Roberts 0:e1e70da93044 1329 {
Wayne Roberts 0:e1e70da93044 1330
Wayne Roberts 0:e1e70da93044 1331 if (msg_type == MSG_TYPE_PER) {
Wayne Roberts 0:e1e70da93044 1332 log_printf("CntPacketTx%u, max:%u ipd%u\r\n", CntPacketTx, MaxNumPacket, tx_ipd_ms);
Wayne Roberts 0:e1e70da93044 1333 if (++CntPacketTx <= MaxNumPacket)
Wayne Roberts 0:e1e70da93044 1334 mbedTimeout.attach_us(next_tx_callback, tx_ipd_ms * 1000);
Wayne Roberts 0:e1e70da93044 1335 } else if (msg_type == MSG_TYPE_PINGPONG) {
Wayne Roberts 0:e1e70da93044 1336 if (flags.ping_master) {
Wayne Roberts 0:e1e70da93044 1337 ++CntPacketTx;
Wayne Roberts 0:e1e70da93044 1338 }
Wayne Roberts 0:e1e70da93044 1339
Wayne Roberts 0:e1e70da93044 1340 Radio::Rx();
Wayne Roberts 0:e1e70da93044 1341 }
Wayne Roberts 0:e1e70da93044 1342 }
Wayne Roberts 0:e1e70da93044 1343
Wayne Roberts 0:e1e70da93044 1344 static void
Wayne Roberts 0:e1e70da93044 1345 printRxPkt(uint8_t size)
Wayne Roberts 0:e1e70da93044 1346 {
Wayne Roberts 0:e1e70da93044 1347 char str[80];
Wayne Roberts 0:e1e70da93044 1348 char *ptr, *endPtr;
Wayne Roberts 0:e1e70da93044 1349 unsigned n = 0;
Wayne Roberts 0:e1e70da93044 1350 endPtr = str + sizeof(str);
Wayne Roberts 0:e1e70da93044 1351 ptr = str;
Wayne Roberts 0:e1e70da93044 1352 while (ptr < endPtr) {
Wayne Roberts 0:e1e70da93044 1353 sprintf(ptr, "%02x ", Radio::radio.rx_buf[n]);
Wayne Roberts 0:e1e70da93044 1354 ptr += 3;
Wayne Roberts 0:e1e70da93044 1355 if (++n >= size)
Wayne Roberts 0:e1e70da93044 1356 break;
Wayne Roberts 0:e1e70da93044 1357 }
Wayne Roberts 0:e1e70da93044 1358 log_printf("%s\r\n", str);
Wayne Roberts 0:e1e70da93044 1359 }
Wayne Roberts 0:e1e70da93044 1360
Wayne Roberts 0:e1e70da93044 1361 void rxDone(uint8_t size, float rssi, float snr)
Wayne Roberts 0:e1e70da93044 1362 {
Wayne Roberts 0:e1e70da93044 1363 log_printf("rxDone %u, %.1fdBm %.1fdB\r\n", size, rssi, snr);
Wayne Roberts 0:e1e70da93044 1364 if (msg_type == MSG_TYPE_PACKET) {
Wayne Roberts 0:e1e70da93044 1365 switch (Radio::radio.rx_buf[0]) {
Wayne Roberts 0:e1e70da93044 1366 displayFloatToInt_t val;
Wayne Roberts 0:e1e70da93044 1367 case CMD_TEMP:
Wayne Roberts 0:e1e70da93044 1368 memcpy(&val, &Radio::radio.rx_buf[1], sizeof(displayFloatToInt_t));
Wayne Roberts 0:e1e70da93044 1369 log_printf("TEMP: %c%d.%02d\r\n", ((val.sign) ? '-' : '+'),
Wayne Roberts 0:e1e70da93044 1370 (int)val.out_int, (int)val.out_dec);
Wayne Roberts 0:e1e70da93044 1371 break;
Wayne Roberts 0:e1e70da93044 1372 case CMD_PRES:
Wayne Roberts 0:e1e70da93044 1373 memcpy(&val, &Radio::radio.rx_buf[1], sizeof(displayFloatToInt_t));
Wayne Roberts 0:e1e70da93044 1374 log_printf("PRESS: %c%d.%02d\r\n", ((val.sign) ? '-' : '+'),
Wayne Roberts 0:e1e70da93044 1375 (int)val.out_int, (int)val.out_dec);
Wayne Roberts 0:e1e70da93044 1376 break;
Wayne Roberts 0:e1e70da93044 1377 case CMD_ACCEL:
Wayne Roberts 0:e1e70da93044 1378 SensorAxes_t acc;
Wayne Roberts 0:e1e70da93044 1379 memcpy(&acc, &Radio::radio.rx_buf[1], sizeof(SensorAxes_t));
Wayne Roberts 0:e1e70da93044 1380 log_printf("ACC %5ld %5ld %5ld\r\n", acc.AXIS_X, acc.AXIS_Y, acc.AXIS_Z);
Wayne Roberts 0:e1e70da93044 1381 break;
Wayne Roberts 0:e1e70da93044 1382 case CMD_PHOTOS:
Wayne Roberts 0:e1e70da93044 1383 uint16_t pv;
Wayne Roberts 0:e1e70da93044 1384 memcpy(&pv, &Radio::radio.rx_buf[1], sizeof(uint16_t));
Wayne Roberts 0:e1e70da93044 1385 log_printf("photos: %u\r\n", pv);
Wayne Roberts 0:e1e70da93044 1386 break;
Wayne Roberts 0:e1e70da93044 1387 default:
Wayne Roberts 0:e1e70da93044 1388 printRxPkt(size);
Wayne Roberts 0:e1e70da93044 1389 break;
Wayne Roberts 0:e1e70da93044 1390 }
Wayne Roberts 0:e1e70da93044 1391 } else if (msg_type == MSG_TYPE_PER) {
Wayne Roberts 0:e1e70da93044 1392 if (memcmp(Radio::radio.rx_buf+4, PerMsg, 3) == 0) {
Wayne Roberts 0:e1e70da93044 1393 unsigned i, PacketRxSequence = Radio::radio.rx_buf[0];
Wayne Roberts 0:e1e70da93044 1394 PacketRxSequence <<= 8;
Wayne Roberts 0:e1e70da93044 1395 PacketRxSequence += Radio::radio.rx_buf[1];
Wayne Roberts 0:e1e70da93044 1396 PacketRxSequence <<= 8;
Wayne Roberts 0:e1e70da93044 1397 PacketRxSequence += Radio::radio.rx_buf[2];
Wayne Roberts 0:e1e70da93044 1398 PacketRxSequence <<= 8;
Wayne Roberts 0:e1e70da93044 1399 PacketRxSequence += Radio::radio.rx_buf[3];
Wayne Roberts 0:e1e70da93044 1400
Wayne Roberts 0:e1e70da93044 1401 CntPacketRxOK++;
Wayne Roberts 0:e1e70da93044 1402
Wayne Roberts 0:e1e70da93044 1403 if (PacketRxSequence <= PacketRxSequencePrev || PacketRxSequencePrev == 0)
Wayne Roberts 0:e1e70da93044 1404 i = 0; // sequence reset to resync, dont count missed packets this time
Wayne Roberts 0:e1e70da93044 1405 else
Wayne Roberts 0:e1e70da93044 1406 i = PacketRxSequence - PacketRxSequencePrev - 1;
Wayne Roberts 0:e1e70da93044 1407
Wayne Roberts 0:e1e70da93044 1408
Wayne Roberts 0:e1e70da93044 1409 CntPacketRxKO += i;
Wayne Roberts 0:e1e70da93044 1410 RxTimeOutCount = 0;
Wayne Roberts 0:e1e70da93044 1411 log_printf("PER rx%u ok%u ko%u\r\n", PacketRxSequence , CntPacketRxOK, CntPacketRxKO);
Wayne Roberts 0:e1e70da93044 1412
Wayne Roberts 0:e1e70da93044 1413 PacketRxSequencePrev = PacketRxSequence;
Wayne Roberts 0:e1e70da93044 1414 } // ..if PerMsg
Wayne Roberts 0:e1e70da93044 1415 else {
Wayne Roberts 0:e1e70da93044 1416 log_printf("per?\r\n");
Wayne Roberts 0:e1e70da93044 1417 printRxPkt(size);
Wayne Roberts 0:e1e70da93044 1418 }
Wayne Roberts 0:e1e70da93044 1419 } else if (msg_type == MSG_TYPE_PINGPONG) {
Wayne Roberts 0:e1e70da93044 1420 if (memcmp(Radio::radio.rx_buf+4, PingMsg, 4) == 0) {
Wayne Roberts 0:e1e70da93044 1421 /* ping slave rx */
Wayne Roberts 0:e1e70da93044 1422 Radio::setFS();
Wayne Roberts 0:e1e70da93044 1423 receivedCntPacket = Radio::radio.rx_buf[0];
Wayne Roberts 0:e1e70da93044 1424 receivedCntPacket <<= 8;
Wayne Roberts 0:e1e70da93044 1425 receivedCntPacket += Radio::radio.rx_buf[1];
Wayne Roberts 0:e1e70da93044 1426 receivedCntPacket <<= 8;
Wayne Roberts 0:e1e70da93044 1427 receivedCntPacket += Radio::radio.rx_buf[2];
Wayne Roberts 0:e1e70da93044 1428 receivedCntPacket <<= 8;
Wayne Roberts 0:e1e70da93044 1429 receivedCntPacket += Radio::radio.rx_buf[3];
Wayne Roberts 0:e1e70da93044 1430 log_printf("%u rxPing->txPong\r\n", receivedCntPacket);
Wayne Roberts 0:e1e70da93044 1431
Wayne Roberts 0:e1e70da93044 1432 flags.ping_master = 0;
Wayne Roberts 0:e1e70da93044 1433 flags.send_pong = 1;
Wayne Roberts 0:e1e70da93044 1434
Wayne Roberts 0:e1e70da93044 1435 } else if (memcmp(Radio::radio.rx_buf+8, PongMsg, 4) == 0) {
Wayne Roberts 0:e1e70da93044 1436 unsigned cnt;
Wayne Roberts 0:e1e70da93044 1437 /* ping master rx */
Wayne Roberts 0:e1e70da93044 1438 Radio::setFS();
Wayne Roberts 0:e1e70da93044 1439 cnt = Radio::radio.rx_buf[0];
Wayne Roberts 0:e1e70da93044 1440 cnt <<= 8;
Wayne Roberts 0:e1e70da93044 1441 cnt += Radio::radio.rx_buf[1];
Wayne Roberts 0:e1e70da93044 1442 cnt <<= 8;
Wayne Roberts 0:e1e70da93044 1443 cnt += Radio::radio.rx_buf[2];
Wayne Roberts 0:e1e70da93044 1444 cnt <<= 8;
Wayne Roberts 0:e1e70da93044 1445 cnt += Radio::radio.rx_buf[3];
Wayne Roberts 0:e1e70da93044 1446 log_printf("%u rxPong->txPing\r\n", cnt);
Wayne Roberts 0:e1e70da93044 1447 flags.send_ping = 1;
Wayne Roberts 0:e1e70da93044 1448 } else {
Wayne Roberts 0:e1e70da93044 1449 log_printf("pingpong?\r\n");
Wayne Roberts 0:e1e70da93044 1450 printRxPkt(size);
Wayne Roberts 0:e1e70da93044 1451 }
Wayne Roberts 0:e1e70da93044 1452 } else {
Wayne Roberts 0:e1e70da93044 1453 /*for (unsigned n = 0; n < size; n++)
Wayne Roberts 0:e1e70da93044 1454 log_printf("%02x\r\n", Radio::radio.rx_buf[n]);*/
Wayne Roberts 0:e1e70da93044 1455 log_printf("msg_type %u\r\n", msg_type);
Wayne Roberts 0:e1e70da93044 1456 }
Wayne Roberts 0:e1e70da93044 1457
Wayne Roberts 0:e1e70da93044 1458 }
Wayne Roberts 0:e1e70da93044 1459
Wayne Roberts 0:e1e70da93044 1460 const RadioEvents_t rev = {
Wayne Roberts 0:e1e70da93044 1461 txDone,
Wayne Roberts 0:e1e70da93044 1462 rxDone
Wayne Roberts 0:e1e70da93044 1463 };
Wayne Roberts 0:e1e70da93044 1464
Wayne Roberts 0:e1e70da93044 1465 static DrvStatusTypeDef LIS2DH12_Read_Single_FIFO_Data(uint16_t sampleIndex, SensorAxes_t* acceleration)
Wayne Roberts 0:e1e70da93044 1466 {
Wayne Roberts 0:e1e70da93044 1467 //SensorAxes_t acceleration;
Wayne Roberts 0:e1e70da93044 1468
Wayne Roberts 0:e1e70da93044 1469 /* Read single FIFO data (acceleration in 3 axes) */
Wayne Roberts 0:e1e70da93044 1470 if (lis2dh12_get_axes(acceleration) == COMPONENT_ERROR)
Wayne Roberts 0:e1e70da93044 1471 {
Wayne Roberts 0:e1e70da93044 1472 return COMPONENT_ERROR;
Wayne Roberts 0:e1e70da93044 1473 }
Wayne Roberts 0:e1e70da93044 1474
Wayne Roberts 0:e1e70da93044 1475 if (sampleIndex < SAMPLE_LIST_MAX)
Wayne Roberts 0:e1e70da93044 1476 {
Wayne Roberts 0:e1e70da93044 1477 log_printf("[DATA %02d] %5ld %5ld %5ld\r\n", sampleIndex + 1, acceleration->AXIS_X,
Wayne Roberts 0:e1e70da93044 1478 acceleration->AXIS_Y,
Wayne Roberts 0:e1e70da93044 1479 acceleration->AXIS_Z);
Wayne Roberts 0:e1e70da93044 1480 }
Wayne Roberts 0:e1e70da93044 1481
Wayne Roberts 0:e1e70da93044 1482 return COMPONENT_OK;
Wayne Roberts 0:e1e70da93044 1483 }
Wayne Roberts 0:e1e70da93044 1484
Wayne Roberts 0:e1e70da93044 1485 void uart_rx_service()
Wayne Roberts 0:e1e70da93044 1486 {
Wayne Roberts 0:e1e70da93044 1487 while (uart_rx_buf_in != uart_rx_buf_out) {
Wayne Roberts 0:e1e70da93044 1488 serial_callback(uart_rx_buf[uart_rx_buf_out++]);
Wayne Roberts 0:e1e70da93044 1489 if (uart_rx_buf_out == UART_RX_BUF_LEN)
Wayne Roberts 0:e1e70da93044 1490 uart_rx_buf_out = 0;
Wayne Roberts 0:e1e70da93044 1491 }
Wayne Roberts 0:e1e70da93044 1492 }
Wayne Roberts 0:e1e70da93044 1493
Wayne Roberts 0:e1e70da93044 1494 static DrvStatusTypeDef LIS2DH12_Read_All_FIFO_Data(void)
Wayne Roberts 0:e1e70da93044 1495 {
Wayne Roberts 0:e1e70da93044 1496 uint16_t samplesToRead = accel_get_num_samples();
Wayne Roberts 0:e1e70da93044 1497 SensorAxes_t acc;
Wayne Roberts 0:e1e70da93044 1498
Wayne Roberts 0:e1e70da93044 1499 /* 'samplesToRead' actually contains number of words in FIFO but each FIFO sample (data set) consists of 3 words
Wayne Roberts 0:e1e70da93044 1500 so the 'samplesToRead' has to be divided by 3 */
Wayne Roberts 0:e1e70da93044 1501 samplesToRead /= 3;
Wayne Roberts 0:e1e70da93044 1502
Wayne Roberts 0:e1e70da93044 1503 log_printf("\r\n%d samples in FIFO.\r\n\r\nStarted downloading data from FIFO ...\r\n", samplesToRead);
Wayne Roberts 0:e1e70da93044 1504
Wayne Roberts 0:e1e70da93044 1505 //wait_ms(1000);
Wayne Roberts 0:e1e70da93044 1506
Wayne Roberts 0:e1e70da93044 1507 log_printf("\r\n[DATA ##] ACC_X ACC_Y ACC_Z [mg]\r\n");
Wayne Roberts 0:e1e70da93044 1508
Wayne Roberts 0:e1e70da93044 1509 for (int i = 0; i < samplesToRead; i++)
Wayne Roberts 0:e1e70da93044 1510 {
Wayne Roberts 0:e1e70da93044 1511 uart_rx_service();
Wayne Roberts 0:e1e70da93044 1512
Wayne Roberts 0:e1e70da93044 1513 if (LIS2DH12_Read_Single_FIFO_Data(i, &acc) == COMPONENT_ERROR)
Wayne Roberts 0:e1e70da93044 1514 {
Wayne Roberts 0:e1e70da93044 1515 return COMPONENT_ERROR;
Wayne Roberts 0:e1e70da93044 1516 } else {
Wayne Roberts 0:e1e70da93044 1517 }
Wayne Roberts 0:e1e70da93044 1518 }
Wayne Roberts 0:e1e70da93044 1519
Wayne Roberts 0:e1e70da93044 1520 if (accel_tx_en) {
Wayne Roberts 0:e1e70da93044 1521 Radio::radio.tx_buf[0] = CMD_ACCEL;
Wayne Roberts 0:e1e70da93044 1522 Radio::set_payload_length(sizeof(SensorAxes_t)+1);
Wayne Roberts 0:e1e70da93044 1523 memcpy(&Radio::radio.tx_buf[1], &acc, sizeof(SensorAxes_t));
Wayne Roberts 0:e1e70da93044 1524 Radio::txPkt();
Wayne Roberts 0:e1e70da93044 1525 }
Wayne Roberts 0:e1e70da93044 1526
Wayne Roberts 0:e1e70da93044 1527 if (samplesToRead > SAMPLE_LIST_MAX)
Wayne Roberts 0:e1e70da93044 1528 {
Wayne Roberts 0:e1e70da93044 1529 log_printf("\r\nSample list limited to: %d\r\n", SAMPLE_LIST_MAX);
Wayne Roberts 0:e1e70da93044 1530 }
Wayne Roberts 0:e1e70da93044 1531
Wayne Roberts 0:e1e70da93044 1532 return COMPONENT_OK;
Wayne Roberts 0:e1e70da93044 1533 }
Wayne Roberts 0:e1e70da93044 1534
Wayne Roberts 0:e1e70da93044 1535
Wayne Roberts 0:e1e70da93044 1536 int main()
Wayne Roberts 0:e1e70da93044 1537 {
Wayne Roberts 0:e1e70da93044 1538
Wayne Roberts 0:e1e70da93044 1539 lfsr = LFSR_INIT;
Wayne Roberts 0:e1e70da93044 1540 msg_type = MSG_TYPE_PACKET;
Wayne Roberts 0:e1e70da93044 1541
Wayne Roberts 0:e1e70da93044 1542 uart_rx_state = URX_STATE_NONE;
Wayne Roberts 0:e1e70da93044 1543 pc.attach(rx_isr);
Wayne Roberts 0:e1e70da93044 1544
Wayne Roberts 0:e1e70da93044 1545 Radio::boardInit(&rev);
Wayne Roberts 0:e1e70da93044 1546
Wayne Roberts 0:e1e70da93044 1547 {
Wayne Roberts 0:e1e70da93044 1548 unsigned n;
Wayne Roberts 0:e1e70da93044 1549 for (n = 0; n < MAX_MENU_ROWS; n++)
Wayne Roberts 0:e1e70da93044 1550 StopMenuCols[n] = -1;
Wayne Roberts 0:e1e70da93044 1551 }
Wayne Roberts 0:e1e70da93044 1552
Wayne Roberts 0:e1e70da93044 1553 botRow = MAX_MENU_ROWS + SCROLLING_ROWS;
Wayne Roberts 0:e1e70da93044 1554
Wayne Roberts 0:e1e70da93044 1555 pc.baud(115200);
Wayne Roberts 0:e1e70da93044 1556 pc.printf("\e[7h"); // enable line wrapping
Wayne Roberts 0:e1e70da93044 1557 pc.printf("\e[%u;%ur", MAX_MENU_ROWS, botRow); // set scrolling region
Wayne Roberts 0:e1e70da93044 1558 pc.printf("\e[2J"); // erase entire screen
Wayne Roberts 0:e1e70da93044 1559
Wayne Roberts 0:e1e70da93044 1560 full_menu_init();
Wayne Roberts 0:e1e70da93044 1561
Wayne Roberts 0:e1e70da93044 1562 pc.printf("\e[2J"); // erase entire screen
Wayne Roberts 0:e1e70da93044 1563
Wayne Roberts 0:e1e70da93044 1564 menuState.mode = MENUMODE_NONE;
Wayne Roberts 0:e1e70da93044 1565
Wayne Roberts 0:e1e70da93044 1566 draw_menu();
Wayne Roberts 0:e1e70da93044 1567
Wayne Roberts 0:e1e70da93044 1568 curpos.row = 0;
Wayne Roberts 0:e1e70da93044 1569 curpos.tableCol = 0;
Wayne Roberts 0:e1e70da93044 1570
Wayne Roberts 0:e1e70da93044 1571 tx_ipd_ms = 100;
Wayne Roberts 0:e1e70da93044 1572
Wayne Roberts 0:e1e70da93044 1573 if (demo_start()) {
Wayne Roberts 0:e1e70da93044 1574 log_printf("demo_start-Failed\r\n");
Wayne Roberts 0:e1e70da93044 1575 for (;;) { asm("nop"); }
Wayne Roberts 0:e1e70da93044 1576 } else
Wayne Roberts 0:e1e70da93044 1577 log_printf("demo_start-OK\r\n");
Wayne Roberts 0:e1e70da93044 1578
Wayne Roberts 0:e1e70da93044 1579
Wayne Roberts 0:e1e70da93044 1580 svc_lis2dh12 = true;
Wayne Roberts 0:e1e70da93044 1581
Wayne Roberts 0:e1e70da93044 1582 for (;;) {
Wayne Roberts 0:e1e70da93044 1583 int ret;
Wayne Roberts 0:e1e70da93044 1584
Wayne Roberts 0:e1e70da93044 1585 uart_rx_service();
Wayne Roberts 0:e1e70da93044 1586
Wayne Roberts 0:e1e70da93044 1587 if (flags.send_ping) {
Wayne Roberts 0:e1e70da93044 1588 if (flags.pingpongEnable)
Wayne Roberts 0:e1e70da93044 1589 SendPing();
Wayne Roberts 0:e1e70da93044 1590 flags.send_ping = 0;
Wayne Roberts 0:e1e70da93044 1591 }
Wayne Roberts 0:e1e70da93044 1592
Wayne Roberts 0:e1e70da93044 1593 if (flags.send_pong) {
Wayne Roberts 0:e1e70da93044 1594 if (flags.pingpongEnable)
Wayne Roberts 0:e1e70da93044 1595 SendPong();
Wayne Roberts 0:e1e70da93044 1596 flags.send_pong = 0;
Wayne Roberts 0:e1e70da93044 1597 }
Wayne Roberts 0:e1e70da93044 1598
Wayne Roberts 0:e1e70da93044 1599 if (flags.do_next_tx) {
Wayne Roberts 0:e1e70da93044 1600 do_next_tx();
Wayne Roberts 0:e1e70da93044 1601 flags.do_next_tx = 0;
Wayne Roberts 0:e1e70da93044 1602 }
Wayne Roberts 0:e1e70da93044 1603
Wayne Roberts 0:e1e70da93044 1604 if (menuState.mode == MENUMODE_REINIT_MENU) {
Wayne Roberts 0:e1e70da93044 1605 full_menu_init();
Wayne Roberts 0:e1e70da93044 1606 menuState.mode = MENUMODE_REDRAW;
Wayne Roberts 0:e1e70da93044 1607 }
Wayne Roberts 0:e1e70da93044 1608
Wayne Roberts 0:e1e70da93044 1609 if (menuState.mode == MENUMODE_REDRAW) {
Wayne Roberts 0:e1e70da93044 1610 // erase entire screen, some dropdowns extend to scrolling area
Wayne Roberts 0:e1e70da93044 1611 pc.printf("\e[%u;%ur", MAX_MENU_ROWS, botRow); // set scrolling region, if terminal started after
Wayne Roberts 0:e1e70da93044 1612 pc.printf("\e[2J");
Wayne Roberts 0:e1e70da93044 1613 //pc.printf("\e[%u;1f\e[1J", MAX_MENU_ROWS); // erase menu area
Wayne Roberts 0:e1e70da93044 1614
Wayne Roberts 0:e1e70da93044 1615 menuState.mode = MENUMODE_NONE;
Wayne Roberts 0:e1e70da93044 1616 draw_menu();
Wayne Roberts 0:e1e70da93044 1617 }
Wayne Roberts 0:e1e70da93044 1618
Wayne Roberts 0:e1e70da93044 1619 if (Radio::service(menuState.mode == MENUMODE_NONE ? LAST_CHIP_MENU_ROW : -1)) {
Wayne Roberts 0:e1e70da93044 1620 read_menu_item(menu_table[curpos.row][curpos.tableCol], true);
Wayne Roberts 0:e1e70da93044 1621 }
Wayne Roberts 0:e1e70da93044 1622
Wayne Roberts 0:e1e70da93044 1623 if (svc_lis2dh12) {
Wayne Roberts 0:e1e70da93044 1624 ret = lis2dh_mainloop();
Wayne Roberts 0:e1e70da93044 1625 switch (ret) {
Wayne Roberts 0:e1e70da93044 1626 case LIS2DH_FAIL_STATE:
Wayne Roberts 0:e1e70da93044 1627 log_printf("lis2dh-stateFail\r\n");
Wayne Roberts 0:e1e70da93044 1628 break;
Wayne Roberts 0:e1e70da93044 1629 case LIS2DH_FAIL:
Wayne Roberts 0:e1e70da93044 1630 log_printf("lis2dh-Fail\r\n");
Wayne Roberts 0:e1e70da93044 1631 break;
Wayne Roberts 0:e1e70da93044 1632 case LIS2DH_BSP_FAIL:
Wayne Roberts 0:e1e70da93044 1633 log_printf("lis2dh bsp-fail\r\n");
Wayne Roberts 0:e1e70da93044 1634 wait(0.05);
Wayne Roberts 0:e1e70da93044 1635 break;
Wayne Roberts 0:e1e70da93044 1636 case LIS2DH_MAIN_SLEEP:
Wayne Roberts 0:e1e70da93044 1637 lis2dh_set_fifo_mode();
Wayne Roberts 0:e1e70da93044 1638
Wayne Roberts 0:e1e70da93044 1639 log_printf("lis2dh fifo-mode-sleep\r\n");
Wayne Roberts 0:e1e70da93044 1640 svc_lis2dh12 = false;
Wayne Roberts 0:e1e70da93044 1641 break;
Wayne Roberts 0:e1e70da93044 1642 case LIS2DH_MAIN_READ_FIFO:
Wayne Roberts 0:e1e70da93044 1643 if (LIS2DH12_Read_All_FIFO_Data() == COMPONENT_ERROR)
Wayne Roberts 0:e1e70da93044 1644 {
Wayne Roberts 0:e1e70da93044 1645 return LIS2DH_FAIL;
Wayne Roberts 0:e1e70da93044 1646 }
Wayne Roberts 0:e1e70da93044 1647
Wayne Roberts 0:e1e70da93044 1648 /* Reset FIFO by setting FIFO mode to Bypass */
Wayne Roberts 0:e1e70da93044 1649 if (lis2dh_set_fifo_bypass() < 0) {
Wayne Roberts 0:e1e70da93044 1650 log_printf("fifo-bypass-fail\r\n");
Wayne Roberts 0:e1e70da93044 1651 }
Wayne Roberts 0:e1e70da93044 1652 break;
Wayne Roberts 0:e1e70da93044 1653 default:
Wayne Roberts 0:e1e70da93044 1654 break;
Wayne Roberts 0:e1e70da93044 1655 }
Wayne Roberts 0:e1e70da93044 1656 } // ..if (svc_lis2dh12)
Wayne Roberts 0:e1e70da93044 1657 else {
Wayne Roberts 0:e1e70da93044 1658 }
Wayne Roberts 0:e1e70da93044 1659
Wayne Roberts 0:e1e70da93044 1660 } // ..for (;;)
Wayne Roberts 0:e1e70da93044 1661 }
Wayne Roberts 0:e1e70da93044 1662
Wayne Roberts 0:e1e70da93044 1663 void lis2dh_int1()
Wayne Roberts 0:e1e70da93044 1664 {
Wayne Roberts 0:e1e70da93044 1665 log_printf("\r\nReceived FIFO Threshold Interrupt on INT1 pin ...\r\n"
Wayne Roberts 0:e1e70da93044 1666 "\r\nNucleo processor is waking up ...\r\n"
Wayne Roberts 0:e1e70da93044 1667 );
Wayne Roberts 0:e1e70da93044 1668
Wayne Roberts 0:e1e70da93044 1669 svc_lis2dh12 = true;
Wayne Roberts 0:e1e70da93044 1670 }
Wayne Roberts 0:e1e70da93044 1671
Wayne Roberts 0:e1e70da93044 1672 char strbuf[255];
Wayne Roberts 0:e1e70da93044 1673
Wayne Roberts 0:e1e70da93044 1674 void c_log_printf(const char* format, ...)
Wayne Roberts 0:e1e70da93044 1675 {
Wayne Roberts 0:e1e70da93044 1676 va_list arglist;
Wayne Roberts 0:e1e70da93044 1677
Wayne Roberts 0:e1e70da93044 1678 // put cursor at last scrolling-area line
Wayne Roberts 0:e1e70da93044 1679 pc.printf("\e[%u;1f", botRow);
Wayne Roberts 0:e1e70da93044 1680 va_start(arglist, format);
Wayne Roberts 0:e1e70da93044 1681 vsnprintf(strbuf, sizeof(strbuf), format, arglist);
Wayne Roberts 0:e1e70da93044 1682 va_end(arglist);
Wayne Roberts 0:e1e70da93044 1683
Wayne Roberts 0:e1e70da93044 1684 pc.printf(strbuf);
Wayne Roberts 0:e1e70da93044 1685 }
Wayne Roberts 0:e1e70da93044 1686
Wayne Roberts 0:e1e70da93044 1687 void log_printf(const char* format, ...)
Wayne Roberts 0:e1e70da93044 1688 {
Wayne Roberts 0:e1e70da93044 1689 va_list arglist;
Wayne Roberts 0:e1e70da93044 1690
Wayne Roberts 0:e1e70da93044 1691 // put cursor at last scrolling-area line
Wayne Roberts 0:e1e70da93044 1692 pc.printf("\e[%u;1f", botRow);
Wayne Roberts 0:e1e70da93044 1693 va_start(arglist, format);
Wayne Roberts 0:e1e70da93044 1694 vsnprintf(strbuf, sizeof(strbuf), format, arglist);
Wayne Roberts 0:e1e70da93044 1695 va_end(arglist);
Wayne Roberts 0:e1e70da93044 1696
Wayne Roberts 0:e1e70da93044 1697 pc.printf(strbuf);
Wayne Roberts 0:e1e70da93044 1698 }
Wayne Roberts 0:e1e70da93044 1699