wayne roberts / Mbed OS utility_sx12xx
Committer:
dudmuck
Date:
Mon Aug 05 20:07:16 2024 +0000
Revision:
15:703ca340d0fb
Parent:
14:14b9e1c08bfc
add reading of RSSI

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