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