NAMote72 Utility Application – Serial Terminal Monitor control for NAMote72 (note: this application replaces the previous na_mote1 test code application)
Dependencies: SX127x lib_gps lib_mma8451q lib_mpl3115a2 lib_sx9500 mbed
Fork of na_mote1 by
See wiki Page for a detailed
This is a link to the wiki page
Diff: main.cpp
- Revision:
- 2:fb41d1c4b299
- Parent:
- 1:b13a15a34c3f
- Child:
- 3:8924027a8933
--- a/main.cpp Mon Oct 06 18:59:49 2014 +0000 +++ b/main.cpp Tue Oct 07 22:16:43 2014 +0000 @@ -9,13 +9,38 @@ * */ Serial pc(USBTX, USBRX); -DigitalInOut pb8(PB_8); -DigitalInOut pb9(PB_9); -//char _pb8, _pb9; -/*I2C i2c(I2C_SDA, I2C_SCL); -MMA8451Q mma8451q(i2c); -MPL3115A2 mpl3115a2(i2c); -SX9500 sx9500(i2c);*/ +#ifdef I2C_PIN_TEST + DigitalInOut pb8(PB_8); + DigitalInOut pb9(PB_9); +#else + I2C i2c(I2C_SDA, I2C_SCL); + MMA8451Q mma8451q(i2c); + //MPL3115A2 mpl3115a2(i2c); + SX9500 sx9500(i2c); +#endif /* I2C_PIN_TeST */ + +DigitalOut pd2(PD_2); + +DigitalOut red_led(PB_1); +DigitalOut green_led(PB_7); +#define LED_ON 0 +#define LED_OFF 1 + +InterruptIn dio3(PC_8); +bool clear_valid_header; + +bool per_en; +int PacketRxSequencePrev; +//uint32_t PacketRxSequence; +uint32_t PacketPerKoCnt; +uint32_t PacketPerOkCnt; +uint32_t PacketNormalCnt; +/*Ticker per_ticker; +float per_tx_interval = 0.1;*/ +Timeout per_timeout; +float per_tx_delay = 0.1; +int per_id; +uint32_t PacketTxCnt; uint8_t tx_cnt; char pcbuf[64]; @@ -855,9 +880,14 @@ void printPa() { + RegPdsTrim1_t pds_trim; + + pds_trim.octet = radio.read_reg(REG_PDSTRIM1); + printf(" txdac=%.1fuA", 2.5 + (pds_trim.bits.prog_txdac * 0.625)); radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG); if (radio.RegPaConfig.bits.PaSelect) { - float output_dBm = 17 - (15-radio.RegPaConfig.bits.OutputPower); + //float output_dBm = 17 - (15-radio.RegPaConfig.bits.OutputPower); + float output_dBm = (pds_trim.bits.prog_txdac+13) - (15-radio.RegPaConfig.bits.OutputPower); printf(" PABOOST OutputPower=%.1fdBm", output_dBm); } else { float pmax = (0.6*radio.RegPaConfig.bits.MaxPower) + 10.8; @@ -869,7 +899,7 @@ void /* things always present, whether lora or fsk */ common_print_status() { - printf("version:0x%02x %.3fMHz ", radio.read_reg(REG_VERSION), radio.get_frf_MHz()); + printf("PD2:%d version:0x%02x %.3fMHz ", pd2.read(), radio.read_reg(REG_VERSION), radio.get_frf_MHz()); printOpMode(); printPa(); @@ -888,9 +918,41 @@ printf(" OcpOFF "); printf("\r\n"); + + if (per_en) { + printf("per_tx_delay:%f\n", per_tx_delay); + printf("PER device ID:%d\n", per_id); + } } +void per_cb() +{ + int i; + + PacketTxCnt++; + + radio.tx_buf[0] = per_id; + radio.tx_buf[1] = PacketTxCnt >> 24; + radio.tx_buf[2] = PacketTxCnt >> 16; + radio.tx_buf[3] = PacketTxCnt >> 8; + radio.tx_buf[4] = PacketTxCnt; + radio.tx_buf[5] = 'P'; + radio.tx_buf[6] = 'E'; + radio.tx_buf[7] = 'R'; + radio.tx_buf[8] = 0; + for (i = 0; i < 8; i++) + radio.tx_buf[8] += radio.tx_buf[i]; + red_led = LED_ON; + lora.start_tx(lora.RegPayloadLength); +} + +void dio3_cb() +{ + green_led = LED_ON; + clear_valid_header = true; +} + void print_rx_buf(int len) { int i; @@ -906,6 +968,24 @@ printf("\r\n"); } +void print_rx_verbose() +{ + float dbm; + printLoraIrqs_(false); + if (lora.RegHopPeriod > 0) { + lora.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL); + printf("HopCH:%d ", lora.RegHopChannel.bits.FhssPresentChannel); + } + lora_printCodingRate(true); // true: of received packet + dbm = lora.get_pkt_rssi(); + printf(" crc%s %.1fdB %.1fdBm\r\n", + lora.RegHopChannel.bits.RxPayloadCrcOn ? "On" : "OFF", + lora.RegPktSnrValue / 4.0, + dbm + ); + print_rx_buf(lora.RegRxNbBytes); +} + void service_radio() { @@ -917,21 +997,43 @@ switch (act) { case SERVICE_READ_FIFO: - float dbm; - if (app == APP_NONE) { - printLoraIrqs_(false); - if (lora.RegHopPeriod > 0) { - lora.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL); - printf("HopCH:%d ", lora.RegHopChannel.bits.FhssPresentChannel); - } - lora_printCodingRate(true); // true: of received packet - dbm = lora.get_pkt_rssi(); - printf(" crc%s %.1fdB %.1fdBm\r\n", - lora.RegHopChannel.bits.RxPayloadCrcOn ? "On" : "OFF", - lora.RegPktSnrValue / 4.0, - dbm - ); - print_rx_buf(lora.RegRxNbBytes); + green_led = LED_OFF; // ValidHeader indication + if (app == APP_NONE) { + if (per_en) { + if (lora.RegRxNbBytes > 8 && radio.rx_buf[5] == 'P' && radio.rx_buf[6] == 'E' && radio.rx_buf[7] == 'R') { + int i; + float per; + red_led = LED_OFF; + /* this is PER packet */ + uint32_t PacketRxSequence = (radio.rx_buf[1] << 24) | (radio.rx_buf[2] << 16) | (radio.rx_buf[3] << 8) | radio.rx_buf[4]; + PacketPerOkCnt++; + //IntervalPerOkCnt++; + + if( PacketRxSequence <= PacketRxSequencePrev ) + { // Sequence went back => resynchronization + // dont count missed packets this time + i = 0; + } + else + { + // determine number of missed packets + i = PacketRxSequence - PacketRxSequencePrev - 1; + } + + // be ready for the next + PacketRxSequencePrev = PacketRxSequence; + // increment 'missed' counter for the RX session + PacketPerKoCnt += i; + //IntervalPerKoCnt += i; + printf("%d, ok=%d missed=%d normal=%d ", PacketRxSequence, PacketPerOkCnt, PacketPerKoCnt, PacketNormalCnt); + per = ( 1.0 - ( float )PacketPerOkCnt / ( float )( PacketPerOkCnt + PacketPerKoCnt ) ) * 100.0; + printf("per:%f\n", per); + } else { + PacketNormalCnt++; + print_rx_verbose(); + } + } else + print_rx_verbose(); } else if (app == APP_CHAT) { if (lora.RegHopChannel.bits.RxPayloadCrcOn) { if (lora.RegIrqFlags.bits.PayloadCrcError) @@ -952,9 +1054,11 @@ } break; case SERVICE_TX_DONE: + red_led = LED_OFF; if (app == APP_CHAT) { lora.start_rx(); - } + } else if (per_en) + per_timeout.attach(&per_cb, per_tx_delay); // start next TX break; case SERVICE_ERROR: printf("error\r\n"); @@ -989,6 +1093,14 @@ break; } // ...switch (act) } + + if (clear_valid_header) { + RegIrqFlags_t irqs; + irqs.octet = 0; + irqs.bits.ValidHeader = 1; + radio.write_reg(REG_LR_IRQFLAGS, irqs.octet); + clear_valid_header = false; + } } int get_kbd_str(char* buf, int size) @@ -1015,6 +1127,7 @@ } } else if (c == 3) { // ctrl-C abort + per_en = false; return -1; } else if (i < size) { buf[i++] = c; @@ -1040,6 +1153,7 @@ if (radio.RegOpMode.bits.LongRangeMode) { lora.RegPayloadLength = len; radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength); + red_led = LED_ON; lora.start_tx(len); } else { fsk.start_tx(len); @@ -1187,20 +1301,26 @@ printf("L toggle LongRangeMode/FSK\r\n"); printf("i radio_init\r\n"); printf("h hw_reset\r\n"); - printf("tx[%%d] transmit\r\n"); + printf("tx[%%d] transmit\r\n"); printf("rx receive\r\n"); printf("C toggle crcOn\r\n"); - printf("op[%%d] get/set output power\r\n"); + printf("op[%%d] get/set output power\r\n"); printf("d[0-5] change DIO pin assignment\r\n"); - printf("frf[%%f} get/set operating frequency (MHz)\r\n"); + printf("frf[%%f] get/set operating frequency (MHz)\r\n"); + printf("pd2 toggle PA_High_Power\r\n"); + printf("bgr[%%d] get/set prog_txdac BGR bias for TXDAC (7=+20dBm)\r\n"); + printf("per toggle PER enable\n"); + printf("pin[%%f] get/set per_tx_delay (seconds)\n"); + printf("pid[%%d] get/set PER device ID\n"); if (radio.RegOpMode.bits.LongRangeMode) { - printf("pl[%%d] LORA get/set RegPayloadLength\r\n"); + printf("pl[%%d] LORA get/set RegPayloadLength\r\n"); printf("cr[1234] LORA set coding rate \r\n"); - printf("bw[%%d] LORA get/set bandwidth\r\n"); - printf("sf[%%d] LORA get/set spreading factor\r\n"); + printf("bw[%%d] LORA get/set bandwidth\r\n"); + printf("sf[%%d] LORA get/set spreading factor\r\n"); printf("T LORA toggle TxContinuousMode\r\n"); - printf("hp[%%d] LORA get/set hop period\r\n"); + printf("hp[%%d] LORA get/set hop period\r\n"); printf("hm LORA toggle explicit/explicit header mode\r\n"); + printf("ld LORA toggle LowDataRateOptimize\r\n"); } else { printf("bw[a][%%d] FSK get-set rxbw (bwa=afcbw)\r\n"); printf("br[%%d] FSK get-set bitrate\r\n"); @@ -1232,14 +1352,20 @@ } else { if (pcbuf[0] == 't' && pcbuf[1] == 'x') { // TX if (radio.RegOpMode.bits.LongRangeMode) { - if (pcbuf[2] >= '0' && pcbuf[2] <= '9') { - sscanf(pcbuf+2, "%d", &i); - lora.RegPayloadLength = i; + if (per_en) { + PacketTxCnt = 0; + per_timeout.attach(&per_cb, per_tx_delay); + } else { + if (pcbuf[2] >= '0' && pcbuf[2] <= '9') { + sscanf(pcbuf+2, "%d", &i); + lora.RegPayloadLength = i; + } + tx_cnt++; + for (i = 0; i < lora.RegPayloadLength; i++) + radio.tx_buf[i] = tx_cnt; + red_led = LED_ON; + lora.start_tx(lora.RegPayloadLength); } - tx_cnt++; - for (i = 0; i < lora.RegPayloadLength; i++) - radio.tx_buf[i] = tx_cnt; - lora.start_tx(lora.RegPayloadLength); } else { // FSK: if (pcbuf[2] >= '0' && pcbuf[2] <= '9') { sscanf(pcbuf+2, "%d", &i); @@ -1286,6 +1412,15 @@ } radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet); } else if (pcbuf[0] == 'r' && pcbuf[1] == 'x') { // RX + if (per_en) { + red_led = LED_OFF; + green_led = LED_OFF; + PacketNormalCnt = 0; + PacketRxSequencePrev = -1; + PacketPerKoCnt = 0; + PacketPerOkCnt = 0; + dio3.rise(&dio3_cb); + } if (radio.RegOpMode.bits.LongRangeMode) lora.start_rx(); else @@ -1297,7 +1432,9 @@ sscanf(pcbuf+2, "%x %x", &i, &len); radio.write_reg(i, len); printf("%02x: %02x\r\n", i, radio.read_reg(i)); - } else if (pcbuf[0] == 'b' && pcbuf[1] == '8') { + } +#ifdef I2C_PIN_TEST + else if (pcbuf[0] == 'b' && pcbuf[1] == '8') { printf("SCL:"); switch (pcbuf[2]) { case '0': @@ -1335,13 +1472,25 @@ break; } printf("\n"); - } /*else if (pcbuf[0] == 'm' && pcbuf[1] == 'm') { - mma8451q.try_read(); - } else if (pcbuf[0] == 'm' && pcbuf[1] == 'p' && pcbuf[2] == 'l') { + } +#else + else if (pcbuf[0] == 'm' && pcbuf[1] == 'm') { + if (pcbuf[2] == 's') + mma8451q.status(); + else if (pcbuf[2] == 'a') { + if (pcbuf[3] == '0' || pcbuf[3] == '1') + mma8451q.set_active(pcbuf[3] - '0'); + else + printf("active:%d\n", mma8451q.get_active()); + } else + mma8451q.try_read(); + } /*else if (pcbuf[0] == 'm' && pcbuf[1] == 'p' && pcbuf[2] == 'l') { mpl3115a2.try_read(); - } else if (pcbuf[0] == '9' && pcbuf[1] == '5') { + }*/ else if (pcbuf[0] == '9' && pcbuf[1] == '5') { sx9500.try_read(); - } */else if (pcbuf[0] == 'm' && pcbuf[1] == 'p' && !radio.RegOpMode.bits.LongRangeMode) { + } +#endif /* !I2C_PIN_TEST */ + else if (pcbuf[0] == 'm' && pcbuf[1] == 'p' && !radio.RegOpMode.bits.LongRangeMode) { radio.RegDioMapping2.bits.MapPreambleDetect ^= 1; radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet); printf("MapPreambleDetect:"); @@ -1394,6 +1543,15 @@ radio.write_reg(REG_FSK_AFCFEI, fsk.RegAfcFei.octet); fsk.RegAfcFei.bits.AfcClear = 0; printf("%dHz\r\n", (int)(FREQ_STEP_HZ * radio.read_s16(REG_FSK_AFCMSB))); + } else if (pcbuf[0] == 'b' && pcbuf[1] == 'g' && pcbuf[2] == 'r') { + RegPdsTrim1_t pds_trim; + pds_trim.octet = radio.read_reg(REG_PDSTRIM1); + if (pcbuf[3] >= '0' && pcbuf[3] <= '9') { + sscanf(&pcbuf[3], "%d", &i); + pds_trim.bits.prog_txdac = i; + } + radio.write_reg(REG_PDSTRIM1, pds_trim.octet); + printf("prog_txdac:%.1fuA\r\n", 2.5 + (pds_trim.bits.prog_txdac * 0.625)); } else if (pcbuf[0] == 'b' && pcbuf[1] == 'r' && !radio.RegOpMode.bits.LongRangeMode) { if (pcbuf[2] >= '0' && pcbuf[2] <= '9') { sscanf(&pcbuf[2], "%d", &i); @@ -1495,6 +1653,40 @@ radio.set_frf_MHz(MHz); } printf("%fMHz\r\n", radio.get_frf_MHz()); + } else if (pcbuf[0] == 'p' && pcbuf[1] == 'i' && pcbuf[2] == 'd') { + if (pcbuf[3] >= '0' && pcbuf[3] <= '9') { + sscanf(pcbuf+3, "%d", &per_id); + } + printf("PER device ID:%d\n", per_id); + } else if (pcbuf[0] == 'p' && pcbuf[1] == 'i' && pcbuf[2] == 'n') { + if (pcbuf[3] >= '0' && pcbuf[3] <= '9') { + sscanf(pcbuf+2, "%f", &per_tx_delay); + } + printf("per_tx_delay:%f\n", per_tx_delay); + } else if (pcbuf[0] == 'p' && pcbuf[1] == 'e' && pcbuf[2] == 'r') { + per_en ^= 1; + printf("per_en:%d\n", per_en); + if (per_en && radio.RegOpMode.bits.LongRangeMode) { + if (radio.type == SX1272) { + lora.RegModemConfig.sx1272bits.LowDataRateOptimize = 1; + radio.write_reg(REG_LR_MODEMCONFIG, lora.RegModemConfig.octet); + } else if (radio.type == SX1276) { + lora.RegModemConfig3.sx1276bits.LowDataRateOptimize = 1; + radio.write_reg(REG_LR_MODEMCONFIG3, lora.RegModemConfig3.octet); + } + lora.RegPayloadLength = 9; + radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength); + radio.RegDioMapping1.bits.Dio3Mapping = 1; // to ValidHeader + radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet); + } + PacketRxSequencePrev = -1; + //PacketRxSequence = 0; + PacketPerKoCnt = 0; + PacketPerOkCnt = 0; + PacketNormalCnt = 0; + if (!per_en) { + per_timeout.detach(); + } } else if (pcbuf[0] == 'p' && pcbuf[1] == 'r' && pcbuf[2] == 'e') { if (radio.RegOpMode.bits.LongRangeMode) { if (pcbuf[3] >= '0' && pcbuf[3] <= '9') { @@ -1518,6 +1710,12 @@ } fsk.RegPreambleDetect.octet = radio.read_reg(REG_FSK_PREAMBLEDETECT); printf("PreambleDetectorTol:%d\r\n", fsk.RegPreambleDetect.bits.PreambleDetectorTol); + } else if (pcbuf[0] == 'p' && pcbuf[1] == 'd' && pcbuf[2] == '2') { + if (pd2.read()) + pd2 = 0; + else + pd2 = 1; + printf("pd2:%d\n", pd2.read()); } else if (pcbuf[0] == 'p' && pcbuf[1] == 'd' && !radio.RegOpMode.bits.LongRangeMode) { fsk.RegPreambleDetect.bits.PreambleDetectorOn ^= 1; radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet); @@ -1534,6 +1732,18 @@ } lora.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH); printf("PayloadLength:%d\r\n", lora.RegPayloadLength); + } else if (pcbuf[0] == 'l' && pcbuf[1] == 'd' && radio.RegOpMode.bits.LongRangeMode) { + if (radio.type == SX1272) { + lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG); + lora.RegModemConfig.sx1272bits.LowDataRateOptimize ^= 1; + printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig.sx1272bits.LowDataRateOptimize); + radio.write_reg(REG_LR_MODEMCONFIG, lora.RegModemConfig.octet); + } else if (radio.type == SX1276) { + lora.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3); + lora.RegModemConfig3.sx1276bits.LowDataRateOptimize ^= 1; + printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig3.sx1276bits.LowDataRateOptimize); + radio.write_reg(REG_LR_MODEMCONFIG3, lora.RegModemConfig3.octet); + } } else if (pcbuf[0] == 'd' && pcbuf[1] >= '0' && pcbuf[1] <= '5') { switch (pcbuf[1]) { case '0': @@ -1567,8 +1777,12 @@ fsk_print_dio(); } else if (pcbuf[0] == 's' && pcbuf[1] == 't' && pcbuf[2] == 'b') { radio.set_opmode(RF_OPMODE_STANDBY); + green_led = LED_OFF; + red_led = LED_OFF; } else if (pcbuf[0] == 's' && pcbuf[1] == 'l' && pcbuf[2] == 'e') { radio.set_opmode(RF_OPMODE_SLEEP); + green_led = LED_OFF; + red_led = LED_OFF; } else if (pcbuf[0] == 'c' && pcbuf[1] == 'h' && pcbuf[2] == 'a') { app = APP_CHAT; lora.start_rx(); @@ -1586,6 +1800,9 @@ pc.baud(57600); radio.frfs = frfs; + + green_led = LED_OFF; + red_led = LED_OFF; while(1) { switch (app) {