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:
Mon Apr 29 13:54:35 2019 -0700
Revision:
2:972a5704f152
Parent:
0:e1e70da93044
add Ticker for polling photo-sensor and pressure/temp-sensor

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