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:
Wayne Roberts
Date:
Sun Nov 25 15:34:40 2018 -0800
Revision:
4:fa31fdf4ec8d
Parent:
3:56fc764dee0a
Child:
5:1e5cb7139acb
add PA-off and xtal trim

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