Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SX127x_modtronix mbed
Fork of chat_sx127x by
Revision 2:c6b23a43a9d9, committed 2014-05-02
- Comitter:
- dudmuck
- Date:
- Fri May 02 01:19:17 2014 +0000
- Parent:
- 1:1cd0afbed23c
- Child:
- 3:ab386fa756cc
- Commit message:
- brought FSK to proper functioning
Changed in this revision
| SX127x.lib | Show annotated file Show diff for this revision Revisions of this file |
| main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/SX127x.lib Wed Apr 30 22:51:34 2014 +0000 +++ b/SX127x.lib Fri May 02 01:19:17 2014 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/dudmuck/code/SX127x/#fdae76e1215e +http://mbed.org/users/dudmuck/code/SX127x/#3bf2515b1eed
--- a/main.cpp Wed Apr 30 22:51:34 2014 +0000
+++ b/main.cpp Fri May 02 01:19:17 2014 +0000
@@ -231,6 +231,7 @@
{
radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
+ printf("DIO5:");
switch (radio.RegDioMapping2.bits.Dio5Mapping) {
case 0: printf("ClkOut"); break;
case 1: printf("PllLock"); break;
@@ -247,6 +248,7 @@
case 3: printf("ModeReady"); break;
}
+ printf(" DIO4:");
switch (radio.RegDioMapping2.bits.Dio4Mapping) {
case 0: printf("temp/eol"); break;
case 1: printf("PllLock"); break;
@@ -264,6 +266,7 @@
radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
+ printf(" DIO3:");
switch (radio.RegDioMapping1.bits.Dio3Mapping) {
case 0: printf("Timeout"); break;
case 1:
@@ -276,6 +279,7 @@
case 3: printf("TempChange/LowBat"); break;
}
+ printf(" DIO2:");
if (fsk.RegPktConfig2.bits.DataModePacket) {
switch (radio.RegDioMapping1.bits.Dio2Mapping) {
case 0: printf("FifoFull"); break;
@@ -287,6 +291,7 @@
printf("Data");
}
+ printf(" DIO1:");
if (fsk.RegPktConfig2.bits.DataModePacket) {
switch (radio.RegDioMapping1.bits.Dio1Mapping) {
case 0: printf("FifoThresh"); break;
@@ -308,6 +313,7 @@
}
}
+ printf(" DIO0:");
if (fsk.RegPktConfig2.bits.DataModePacket) {
switch (radio.RegDioMapping1.bits.Dio0Mapping) {
case 0: printf("PayloadReady/PacketSent"); break;
@@ -468,34 +474,34 @@
void fsk_print_IrqFlags2()
{
- FSKRegIrqFlags2_t FSKRegIrqFlags2;
+ RegIrqFlags2_t RegIrqFlags2;
printf("IrqFlags2: ");
- FSKRegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
- if (FSKRegIrqFlags2.bits.FifoFull)
+ RegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
+ if (RegIrqFlags2.bits.FifoFull)
printf("FifoFull ");
- if (FSKRegIrqFlags2.bits.FifoEmpty)
+ if (RegIrqFlags2.bits.FifoEmpty)
printf("FifoEmpty ");
- if (FSKRegIrqFlags2.bits.FifoLevel)
+ if (RegIrqFlags2.bits.FifoLevel)
printf("FifoLevel ");
- if (FSKRegIrqFlags2.bits.FifoOverrun)
+ if (RegIrqFlags2.bits.FifoOverrun)
printf("FifoOverrun ");
- if (FSKRegIrqFlags2.bits.PacketSent)
+ if (RegIrqFlags2.bits.PacketSent)
printf("PacketSent ");
- if (FSKRegIrqFlags2.bits.PayloadReady)
+ if (RegIrqFlags2.bits.PayloadReady)
printf("PayloadReady ");
- if (FSKRegIrqFlags2.bits.CrcOk)
+ if (RegIrqFlags2.bits.CrcOk)
printf("CrcOk ");
- if (FSKRegIrqFlags2.bits.LowBat)
+ if (RegIrqFlags2.bits.LowBat)
printf("LowBat ");
- printf("\n");
+ printf("\r\n");
}
void
fsk_print_status()
{
//uint16_t s;
- FSKRegIrqFlags1_t FSKRegIrqFlags1;
+ RegIrqFlags1_t RegIrqFlags1;
if (radio.RegOpMode.bits.LongRangeMode) {
printf("LoRa\r\n");
@@ -588,7 +594,6 @@
printf("\r\n");
fsk_print_IrqFlags2();
- printf("\r\n");
} else {
/* continuous mode */
printf("[7mcontinuous[27m ");
@@ -764,22 +769,22 @@
} // ..if sequencer enabled
printf("\r\nIrqFlags1:");
- FSKRegIrqFlags1.octet = radio.read_reg(REG_FSK_IRQFLAGS1);
- if (FSKRegIrqFlags1.bits.ModeReady)
+ RegIrqFlags1.octet = radio.read_reg(REG_FSK_IRQFLAGS1);
+ if (RegIrqFlags1.bits.ModeReady)
printf("ModeReady ");
- if (FSKRegIrqFlags1.bits.RxReady)
+ if (RegIrqFlags1.bits.RxReady)
printf("RxReady ");
- if (FSKRegIrqFlags1.bits.TxReady)
+ if (RegIrqFlags1.bits.TxReady)
printf("TxReady ");
- if (FSKRegIrqFlags1.bits.PllLock)
+ if (RegIrqFlags1.bits.PllLock)
printf("PllLock ");
- if (FSKRegIrqFlags1.bits.Rssi)
+ if (RegIrqFlags1.bits.Rssi)
printf("Rssi ");
- if (FSKRegIrqFlags1.bits.Timeout)
+ if (RegIrqFlags1.bits.Timeout)
printf("Timeout ");
- if (FSKRegIrqFlags1.bits.PreambleDetect)
+ if (RegIrqFlags1.bits.PreambleDetect)
printf("PreambleDetect ");
- if (FSKRegIrqFlags1.bits.SyncAddressMatch)
+ if (RegIrqFlags1.bits.SyncAddressMatch)
printf("SyncAddressMatch ");
printf("\r\n");
@@ -953,7 +958,27 @@
switch (act) {
case SERVICE_READ_FIFO:
+ if (app == APP_CHAT) {
+ int n = fsk.rx_buf_length;
+ radio.rx_buf[n++] = '\r';
+ radio.rx_buf[n++] = '\n';
+ radio.rx_buf[n] = 0; // null terminate
+ printf((char *)radio.rx_buf);
+ } else {
+ int i;
+ if (fsk.RegRxConfig.bits.AfcAutoOn)
+ printf("%dHz ", (int)(FREQ_STEP_HZ * fsk.RegAfcValue));
+ printf("%d: ", fsk.rx_buf_length);
+ for (i = 0; i < fsk.rx_buf_length; i++)
+ printf("%02x ", radio.rx_buf[i]);
+ printf("\r\n");
+ }
break;
+ case SERVICE_TX_DONE:
+ if (app == APP_CHAT) {
+ fsk.start_rx();
+ }
+ break;
} // ...switch (act)
}
}
@@ -1012,8 +1037,9 @@
lora.RegPayloadLength = len;
radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
lora.start_tx(len);
- } else
- printf("todo fsk tx\r\n");
+ } else {
+ fsk.start_tx(len);
+ }
printf("\r\n");
}
}
@@ -1022,6 +1048,7 @@
console()
{
int len, i;
+ uint32_t ui;
uint8_t a, d;
static uint16_t fsk_tx_length;
@@ -1064,8 +1091,21 @@
}
break;
case 'C':
- lora.setRxPayloadCrcOn(!lora.getRxPayloadCrcOn());
- lora_printRxPayloadCrcOn();
+ if (radio.RegOpMode.bits.LongRangeMode) {
+ lora.setRxPayloadCrcOn(!lora.getRxPayloadCrcOn());
+ lora_printRxPayloadCrcOn();
+ } else {
+ printf("CrcOn:");
+ fsk.RegPktConfig1.bits.CrcOn ^= 1;
+ radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
+ if (fsk.RegPktConfig1.bits.CrcOn)
+ printf("On\r\n");
+ else
+ printf("Off\r\n");
+ if (fsk.RegPktConfig2.bits.DataModePacket && radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
+ fsk.config_dio0_for_pktmode_rx();
+ }
+ }
printf("\r\n");
break;
case 'B':
@@ -1085,26 +1125,87 @@
printf("LoRa\r\n");
else
printf("FSK\r\n");
- break;
+ break;
+ case 's':
+ if (!radio.RegOpMode.bits.LongRangeMode) {
+ fsk.RegFifoThreshold.bits.TxStartCondition ^= 1;
+ radio.write_reg(REG_FSK_FIFOTHRESH, fsk.RegFifoThreshold.octet);
+ printf("TxStartCondition:");
+ if (fsk.RegFifoThreshold.bits.TxStartCondition)
+ printf("!FifoEmpty\r\n");
+ else
+ printf("FifoLevel\r\n");
+ }
+ break;
+ case 'f':
+ if (!radio.RegOpMode.bits.LongRangeMode) {
+ printf("PacketFormat:");
+ fsk.RegPktConfig1.bits.PacketFormatVariable ^= 1;
+ radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
+ if (fsk.RegPktConfig1.bits.PacketFormatVariable)
+ printf("variable\r\n");
+ else
+ printf("fixed\r\n");
+ /*if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER)
+ reset_flow();*/
+ }
+ break;
+ case 'E':
+ if (!radio.RegOpMode.bits.LongRangeMode) {
+ RegIrqFlags2_t RegIrqFlags2;
+ RegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
+ while (!RegIrqFlags2.bits.FifoEmpty) {
+ if (pc.readable())
+ break;
+ printf("%02x\r\n", radio.read_reg(REG_FIFO));
+ RegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
+ }
+ }
+ break;
+ case 'A':
+ if (!radio.RegOpMode.bits.LongRangeMode) {
+ fsk.RegRxConfig.bits.AfcAutoOn ^= 1;
+ radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
+ printf("AfcAuto:");
+ if (fsk.RegRxConfig.bits.AfcAutoOn)
+ printf("On\r\n");
+ else
+ printf("OFF\r\n");
+ break;
+ }
+ break;
case '?':
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");
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");
} else {
- printf("bw[%%d] FSK get-set rxbw\n");
+ printf("bw[a][%%d] FSK get-set rxbw (bwa=afcbw)\r\n");
+ printf("rt FSK change RxTrigger\r\n");
+ printf("pd FSK enable/disable preamble detector\r\n");
+ printf("pt FSK get-set PreambleDetectorTol\r\n");
+ printf("ss[%%d] FSK get-set SyncSize\r\n");
+ printf("S[%%x] FSK get-set sync word\r\n");
+ printf("s FSK toggle TxStartCondition\r\n");
+ printf("f FSK toggle PacketFormat fixed-variable\r\n");
+ printf("E FSK empty out the fifo\r\n");
+ printf("ac FSK AfcClear\r\n");
+ printf("A FSK toggle AfcAutoOn\r\n");
+ printf("mp FSK toggle MapPreambleDetect\r\n");
+ printf("ar FSK change AutoRestartRxMode\r\n");
+ printf("alc FSK toggle AfcAutoClearOn\r\n");
}
break;
case '.':
@@ -1119,22 +1220,25 @@
if (pcbuf[0] == 't' && pcbuf[1] == 'x') { // TX
if (radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
- sscanf(pcbuf+3, "%d", &i);
+ sscanf(pcbuf+2, "%d", &i);
lora.RegPayloadLength = i;
}
tx_cnt++;
for (i = 0; i < lora.RegPayloadLength; i++)
radio.tx_buf[i] = tx_cnt;
lora.start_tx(lora.RegPayloadLength);
- } else {
+ } else { // FSK:
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
- sscanf(pcbuf+3, "%d", &i);
+ sscanf(pcbuf+2, "%d", &i);
fsk_tx_length = i;
}
- tx_cnt++;
- for (i = 0; i < fsk_tx_length; i++)
- radio.tx_buf[i] = tx_cnt;
- fsk.start_tx(fsk_tx_length);
+ if (radio.RegOpMode.bits.Mode != RF_OPMODE_TRANSMITTER) { // if not already busy transmitting
+ tx_cnt++;
+ for (i = 0; i < fsk_tx_length; i++) {
+ radio.tx_buf[i] = tx_cnt;
+ }
+ fsk.start_tx(fsk_tx_length);
+ }
}
} else if (pcbuf[0] == 'h' && pcbuf[1] == 'p' && radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
@@ -1148,8 +1252,31 @@
}
lora.RegHopPeriod = radio.read_reg(REG_LR_HOPPERIOD);
printf("HopPeriod:0x%02x\r\n", lora.RegHopPeriod);
+ } else if (pcbuf[0] == 'r' && pcbuf[1] == 't' && !radio.RegOpMode.bits.LongRangeMode) {
+ printf("RxTrigger:");
+ switch (fsk.RegRxConfig.bits.RxTrigger) {
+ case 0: fsk.RegRxConfig.bits.RxTrigger = 1;
+ printf("rssi\r\n");
+ break;
+ case 1: fsk.RegRxConfig.bits.RxTrigger = 6;
+ printf("preamble\r\n");
+ break;
+ case 6: fsk.RegRxConfig.bits.RxTrigger = 7;
+ printf("both\r\n");
+ break;
+ case 7: fsk.RegRxConfig.bits.RxTrigger = 0;
+ printf("none\r\n");
+ break;
+ default: fsk.RegRxConfig.bits.RxTrigger = 0;
+ printf("none\r\n");
+ break;
+ }
+ radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
} else if (pcbuf[0] == 'r' && pcbuf[1] == 'x') { // RX
- lora.start_rx();
+ if (radio.RegOpMode.bits.LongRangeMode)
+ lora.start_rx();
+ else
+ fsk.start_rx();
} else if (pcbuf[0] == 'r' && pcbuf[1] == ' ') { // read single register
sscanf(pcbuf+2, "%x", &i);
printf("%02x: %02x\r\n", i, radio.read_reg(i));
@@ -1157,6 +1284,14 @@
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] == 'm' && pcbuf[1] == 'p' && !radio.RegOpMode.bits.LongRangeMode) {
+ radio.RegDioMapping2.bits.MapPreambleDetect ^= 1;
+ radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);
+ printf("MapPreambleDetect:");
+ if (radio.RegDioMapping2.bits.MapPreambleDetect)
+ printf("preamble\r\n");
+ else
+ printf("rssi\r\n");
} else if (pcbuf[0] == 'o' && pcbuf[1] == 'p') {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%d", &i);
@@ -1176,6 +1311,32 @@
lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
lora_printHeaderMode();
printf("\r\n");
+ } else if (pcbuf[0] == 'a' && pcbuf[1] == 'l' && !radio.RegOpMode.bits.LongRangeMode) {
+ fsk.RegAfcFei.bits.AfcAutoClearOn ^= 1;
+ printf("AfcAutoClearOn: ");
+ radio.write_reg(REG_FSK_AFCFEI, fsk.RegAfcFei.octet);
+ if (fsk.RegAfcFei.bits.AfcAutoClearOn)
+ printf("ON\r\n");
+ else
+ printf("off\r\n");
+ } else if (pcbuf[0] == 'a' && pcbuf[1] == 'r' && !radio.RegOpMode.bits.LongRangeMode) {
+ fsk.RegSyncConfig.bits.AutoRestartRxMode++;
+ radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
+ fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
+ printf("AutoRestartRxMode:");
+ switch (fsk.RegSyncConfig.bits.AutoRestartRxMode) {
+ case 0: printf("off "); break;
+ case 1: printf("no-pll-wait "); break;
+ case 2: printf("pll-wait "); break;
+ case 3: printf("3 "); break;
+ }
+ printf("\r\n");
+ } else if (pcbuf[0] == 'a' && pcbuf[1] == 'c' && !radio.RegOpMode.bits.LongRangeMode) {
+ printf("clear afc: ");
+ fsk.RegAfcFei.bits.AfcClear = 1;
+ 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] == 'w') {
if (radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
@@ -1208,6 +1369,43 @@
} else if (pcbuf[0] == 'v' && pcbuf[1] == 'h') {
lora.poll_vh ^= 1;
printf("poll_vh:%d\r\n", lora.poll_vh);
+ } else if (pcbuf[0] == 'S' && !radio.RegOpMode.bits.LongRangeMode) {
+ if (pcbuf[1] == '0') {
+ sscanf(pcbuf+1, "%x", &ui);
+ if (ui < 0x100) {
+ fsk.RegSyncConfig.bits.SyncSize = 0;
+ radio.write_reg(REG_FSK_SYNCVALUE1, ui);
+ } else if (ui < 0x10000) {
+ fsk.RegSyncConfig.bits.SyncSize = 1;
+ radio.write_reg(REG_FSK_SYNCVALUE1, ui & 0xff);
+ radio.write_reg(REG_FSK_SYNCVALUE2, ui >> 8);
+ } else if (ui < 0x1000000) {
+ fsk.RegSyncConfig.bits.SyncSize = 2;
+ radio.write_reg(REG_FSK_SYNCVALUE1, ui & 0xff);
+ radio.write_reg(REG_FSK_SYNCVALUE2, (ui >> 8) & 0xff);
+ radio.write_reg(REG_FSK_SYNCVALUE3, ui >> 16);
+ } else {
+ fsk.RegSyncConfig.bits.SyncSize = 3;
+ radio.write_reg(REG_FSK_SYNCVALUE1, ui & 0xff);
+ radio.write_reg(REG_FSK_SYNCVALUE2, (ui >> 8) & 0xff);
+ radio.write_reg(REG_FSK_SYNCVALUE3, (ui >> 16) & 0xff);
+ radio.write_reg(REG_FSK_SYNCVALUE4, ui >> 24);
+ }
+ radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
+ }
+ fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
+ printf("%d: ", fsk.RegSyncConfig.bits.SyncSize);
+ for (i = 0; i <= fsk.RegSyncConfig.bits.SyncSize; i++)
+ printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE1+i));
+ printf("\r\n");
+ } else if (pcbuf[0] == 's' && pcbuf[1] == 's' && !radio.RegOpMode.bits.LongRangeMode) {
+ if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
+ sscanf(pcbuf+2, "%d", &i);
+ fsk.RegSyncConfig.bits.SyncSize = i;
+ radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
+ }
+ fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
+ printf("SyncSize:%d\r\n", fsk.RegSyncConfig.bits.SyncSize);
} else if (pcbuf[0] == 's' && pcbuf[1] == 'f' && radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%d", &i);
@@ -1228,6 +1426,22 @@
radio.set_frf_MHz(MHz);
} else
printf("%fMHz\r\n", radio.get_frf_MHz());
+ } else if (pcbuf[0] == 'p' && pcbuf[1] == 't' && !radio.RegOpMode.bits.LongRangeMode) {
+ if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
+ sscanf(pcbuf+2, "%d", &i);
+ fsk.RegPreambleDetect.bits.PreambleDetectorTol = i;
+ radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet);
+ }
+ 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' && !radio.RegOpMode.bits.LongRangeMode) {
+ fsk.RegPreambleDetect.bits.PreambleDetectorOn ^= 1;
+ radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet);
+ printf("PreambleDetector:");
+ if (fsk.RegPreambleDetect.bits.PreambleDetectorOn)
+ printf("On\r\n");
+ else
+ printf("OFF\r\n");
} else if (pcbuf[0] == 'p' && pcbuf[1] == 'l' && radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%d", &i);
