Text menu driven ANSI/VT100 console test utility for LoRa transceivers

radio chip selection

Radio chip driver is not included, allowing choice of radio device.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
if you're using SX1280, then import sx1280 driver into your program.
if you're using LR1110, then import LR1110 driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.
If you're using Type1SJ select target DISCO_L072CZ_LRWAN1 and import sx126x driver into your program.

This is VT100 text-based menu driven test program for SX12xx transceiver devices.
Serial console is divided into horizontally into top half and bottom half.
The bottom half serves as scrolling area to log activity.
The top half serves as menu, to configure the radio.
For all devices, the serial console operates at 115200 8N1, and requires terminal with ANSI-VT100 capability, such as putty/teraterm/minicom etc.
Use program only with keyboard up/down/left/right keys. Enter to change an item, or number for value item. Some items are single bit, requiring only enter key to toggle. Others with fixed choices give a drop-down menu.

Committer:
dudmuck
Date:
Tue Aug 24 16:21:28 2021 -0700
Revision:
13:8ce61a1897ab
Parent:
9:295e37c38fb3
Child:
14:14b9e1c08bfc
add RF frequency sweep for continuous_tx

Who changed what in which revision?

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