This program enables the use of the Semtech "SX1276 Starter Kit A" application to be used with the FRDM-KL25Z board. At the time of writing this, this app was available on Semtech's SX1276 page, in the "Docs & Resources"* tab, via the link "PC GUI (1.0.0Beta5)". This program was tested with the FRDM-KL25Z board, with a Modtronix inAir9 SX1276 board mounted in a Modtronix SHD3I shield. The inAir9 module is mounted in iMod port 3 of the SHD3I module. The SHD3I shield is mounted on the FRDM-KL25Z board.

Dependencies:   SX127x_modtronix USBDevice_Semtech_GUI mbed

Fork of hid_test by wayne roberts

Files at this revision

API Documentation at this revision

Comitter:
dudmuck
Date:
Mon Apr 14 22:01:41 2014 +0000
Child:
1:d25ba61cd2f3
Commit message:
initial commit

Changed in this revision

SX127x.lib Show annotated file Show diff for this revision Revisions of this file
USBDevice.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
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SX127x.lib	Mon Apr 14 22:01:41 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/dudmuck/code/SX127x/#7dc60eb4c7ec
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice.lib	Mon Apr 14 22:01:41 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/USBDevice/#5b7d31d9d3f3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Apr 14 22:01:41 2014 +0000
@@ -0,0 +1,669 @@
+#include "mbed.h"
+#include "USBHID.h"
+#include "sx127x.h"
+
+//  pin:      3     8     1      7    10    12     5   20    18
+//           mosi, miso, sclk,   cs,  rst,  dio0, dio1, fctx, fcps 
+SX127x radio(PTD2, PTD3, PTD1, PTD0, PTD5, PTA13, PTD4, PTC9, PTC8);
+
+//We declare a USBHID device. By default input and output reports are 64 bytes long.
+USBHID hid(64, 64, 0x47a, 0x0b);
+//USBHID (uint8_t output_report_length=64, uint8_t input_report_length=64, uint16_t vendor_id=0x1234, uint16_t product_id=0x0006, uint16_t product_release=0x0001, bool connect=true) 
+ 
+Serial pc(USBTX, USBRX);
+ 
+//This report will contain data to be sent
+HID_REPORT send_report;
+HID_REPORT recv_report;
+ 
+DigitalOut l1(LED1);
+
+#define FW_VERSION                                  "3.1.0"
+#define SK_NAME                                     "mbed"
+
+#define HID_SK_RESET                                0x00
+#define HID_SK_GET_VERSION                          0x01
+#define HID_SK_GET_NAME                             0x02
+#define HID_SK_GET_PIN                              0x10
+#define HID_SK_SET_PIN                              0x11
+#define HID_SK_GET_PINS                             0x14
+#define HID_DEVICE_READ                             0x80
+#define HID_DEVICE_WRITE                            0x81
+#define HID_DEVICE_INIT                             0x88
+#define HID_DEVICE_RESET                            0x89
+#define HID_SK_CMD_NONE                             0xFF
+
+typedef struct sHidCommand
+{
+    uint8_t Cmd;
+    uint8_t CmdOpt;
+    uint8_t CmdDataSize;
+    uint8_t *CmdData;
+} tHidCommand;
+
+typedef enum
+{
+    SX_OK,
+    SX_ERROR,
+    SX_BUSY,
+    SX_EMPTY,
+    SX_DONE,
+    SX_TIMEOUT,
+    SX_UNSUPPORTED,
+    SX_WAIT,
+    SX_CLOSE,
+    SX_YES,
+    SX_NO,          
+} tReturnCodes;
+
+#ifdef _DEBUG_
+char verbose = 0;
+#endif /* _DEBUG_ */
+
+void HidDecodeCommand( uint8_t *hidReport, tHidCommand *cmd )
+{
+    cmd->Cmd = hidReport[0];
+    cmd->CmdOpt = hidReport[1];
+    cmd->CmdDataSize = hidReport[2];
+    cmd->CmdData = hidReport + 3;
+}
+
+void HidEncodeCommandAns( uint8_t cmd, uint8_t stat, uint8_t dataSize, uint8_t *data )
+{
+    send_report.data[0] =  cmd;
+    send_report.data[1] =  stat;
+
+    // TimeStamp
+    memset( send_report.data + 2, 0, 8 );
+
+    send_report.data[10] =  dataSize;
+    memcpy( send_report.data + 11, ( const void* )data, dataSize );
+    
+    //send_report.length = 11 + dataSize;
+    send_report.length = 64;
+    hid.send(&send_report);
+}
+
+void HidCmdProcess(void)
+{
+    uint8_t stat = SX_OK;
+    uint8_t size = 0;
+    uint8_t dataBuffer[64];
+    tHidCommand cmd = { HID_SK_CMD_NONE, 0, 0, NULL };
+    #ifdef _DEBUG_
+    int i;
+    #endif /* _DEBUG_ */
+
+    HidDecodeCommand(recv_report.data, &cmd);
+    
+    switch (cmd.Cmd) {
+        case HID_DEVICE_RESET:
+            radio.hw_reset();
+            break;
+        case HID_SK_RESET:
+        case HID_DEVICE_INIT:
+            radio.hw_reset();
+            #ifdef _DEBUG_
+            if (verbose)
+                printf("reset-init\r\n");
+            #endif /* _DEBUG_ */
+            radio.init();   //SX1272Init( );
+            // Set FSK modem ON
+            radio.SetLoRaOn( false ); //SX1272SetLoRaOn( false ); // Default radio setting
+            // Default answer settings
+            break;
+        case HID_SK_GET_VERSION:
+            strcpy( ( char* )dataBuffer, FW_VERSION );
+            size = strlen( FW_VERSION );
+            break;
+        case HID_DEVICE_READ:
+            // cmd.CmdData[0] = size
+            // cmd.CmdData[1] = address
+            size = cmd.CmdData[0];
+            radio.ReadBuffer( cmd.CmdData[1], dataBuffer, size );
+            #ifdef _DEBUG_
+            if (verbose) {
+                pc.printf("read %d bytes from %02x: ", size, cmd.CmdData[1]);
+                for (i = 0; i < size; i++)
+                    pc.printf("%02x ", dataBuffer[i]);
+                pc.printf("\r\n");
+            }
+            #endif /* _DEBUG_ */
+            stat = SX_OK;
+            break;
+        case HID_SK_GET_PINS:
+            dataBuffer[0] = 0;
+            if (radio.dio0)
+                dataBuffer[0] |= 0x01;
+            if (radio.dio1)
+                dataBuffer[0] |= 0x02;
+            #ifdef _DEBUG_
+            if (verbose && dataBuffer[0] != 0)
+                printf("HID_SK_GET_PINS:%02x\r\n", dataBuffer[0]);
+            #endif /* _DEBUG_ */
+            /*dataBuffer[0] |= DIO1 << 1;
+            dataBuffer[0] |= DIO2 << 2;
+            dataBuffer[0] |= DIO3 << 3;
+            dataBuffer[0] |= DIO4 << 4;
+            dataBuffer[0] |= DIO5 << 5;*/
+            size = 1;
+            break;
+        case HID_SK_GET_PIN:
+            // cmd.CmdData[0] = Pin id
+            switch( cmd.CmdData[0] ) {
+                case 11:    // FEM_CPS_PIN
+                    dataBuffer[0] = radio.femcps;
+                    #ifdef _DEBUG_
+                    if (verbose)
+                        printf("HID_SK_GET_PIN femcps:%02x\r\n", dataBuffer[0]);
+                    #endif /* _DEBUG_ */
+                    break;
+                case 12:    // FEM_CTX_PIN
+                    dataBuffer[0] = radio.femctx;
+                    #ifdef _DEBUG_
+                    if (verbose)
+                        printf("HID_SK_GET_PIN femctx:%02x\r\n", dataBuffer[0]);
+                    #endif /* _DEBUG_ */
+                    break;
+                default:
+                    dataBuffer[0] = 0xFF; // Signal ID error
+                    #ifdef _DEBUG_
+                    printf("HID_SK_GET_PIN %d\r\n", cmd.CmdData[0]);
+                    #endif /* _DEBUG_ */
+                    break;
+            } // ...switch( cmd.CmdData[0] )
+            break;
+        case HID_SK_SET_PIN:
+            // cmd.CmdData[0] = Pin id
+            // cmd.CmdData[1] = Pin state
+            switch( cmd.CmdData[0] ) {
+                case 6:
+                case 7:
+                case 8:
+                    // ignore LEDs
+                    break;
+                case 11:    // FEM_CPS_PIN
+                    radio.femcps = cmd.CmdData[1];
+                    #ifdef _DEBUG_
+                    if (verbose)
+                        printf("HID_SK_SET_PIN femcps:%d\r\n", (int)radio.femcps);
+                    #endif /* _DEBUG_ */
+                    break;                    
+                case 12:    // FEM_CTX_PIN
+                    radio.femctx = cmd.CmdData[1];
+                    #ifdef _DEBUG_
+                    if (verbose)
+                        printf("HID_SK_SET_PIN femctx:%d\r\n", (int)radio.femctx); 
+                    #endif /* _DEBUG_ */
+                    break;
+                default:
+                    stat = SX_UNSUPPORTED;
+                    #ifdef _DEBUG_
+                    pc.printf("HID_SK_SET_PIN %d %d\r\n", cmd.CmdData[0], cmd.CmdData[1]);
+                    #endif /* _DEBUG_ */
+                    break;
+            } // ...switch( cmd.CmdData[0] )
+            
+            break;
+        case HID_DEVICE_WRITE:
+            // cmd.CmdData[0] = size
+            // cmd.CmdData[1] = address
+            // cmd.CmdData[2] = Buffer first byte
+            // cmd.CmdData[2+(size-1)] = Buffer last byte
+            radio.WriteBuffer( cmd.CmdData[1], cmd.CmdData + 2, cmd.CmdData[0] );
+            #ifdef _DEBUG_
+            if (verbose) {
+                pc.printf("write %d bytes to %02x: ", cmd.CmdData[0], cmd.CmdData[1]);
+                for (i = 0; i < cmd.CmdData[0]; i++)
+                    pc.printf("%02x ", cmd.CmdData[2+i]);
+                pc.printf("\r\n");
+            }
+            #endif /* _DEBUG_ */
+            stat = SX_OK;
+            break;
+        case HID_SK_GET_NAME:
+            strcpy( ( char* )dataBuffer, SK_NAME );
+            size = strlen( SK_NAME );
+            break;            
+        default:
+            pc.printf("%d: ", recv_report.length);
+            for(int i = 0; i < recv_report.length; i++) {
+                pc.printf("%02x ", recv_report.data[i]);
+            }
+            pc.printf("\r\n");
+            stat = SX_UNSUPPORTED;
+        break;
+    } // ...switch (cmd.Cmd)
+    
+    HidEncodeCommandAns( cmd.Cmd, stat, size, dataBuffer);
+}
+
+#ifdef _DEBUG_
+void printOpMode()
+{
+    radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
+    switch (radio.RegOpMode.bits.Mode) {
+        case RF_OPMODE_SLEEP: printf("sleep"); break;
+        case RF_OPMODE_STANDBY: printf("stby"); break;
+        case RF_OPMODE_SYNTHESIZER_TX: printf("fstx"); break;
+        case RF_OPMODE_TRANSMITTER: printf("tx"); break;
+        case RF_OPMODE_SYNTHESIZER_RX: printf("fsrx"); break;
+        case RF_OPMODE_RECEIVER: printf("rx"); break;
+        case 6:
+            if (radio.RegOpMode.bits.LongRangeMode)
+                printf("rxs");
+            else
+                printf("-6-");
+            break;  // todo: different lora/fsk
+        case 7:
+            if (radio.RegOpMode.bits.LongRangeMode)
+                printf("cad");
+            else
+                printf("-7-");
+            break;  // todo: different lora/fsk
+    }
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+void
+printPa()
+{
+    radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
+    if (radio.RegPaConfig.bits.PaSelect) {
+        float output_dBm = 17 - (15-radio.RegPaConfig.bits.OutputPower);
+        printf(" PABOOST OutputPower=%.1fdBm", output_dBm);
+    } else {
+        float pmax = (0.6*radio.RegPaConfig.bits.MaxPower) + 10.8;
+        float output_dBm = pmax - (15-radio.RegPaConfig.bits.OutputPower);
+        printf(" RFO pmax=%.1fdBm OutputPower=%.1fdBm", pmax, output_dBm);
+    }
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+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());
+    printOpMode();
+
+    printPa();
+
+    radio.RegOcp.octet = radio.read_reg(REG_OCP);
+    if (radio.RegOcp.bits.OcpOn) {
+        int imax = 0;
+        if (radio.RegOcp.bits.OcpTrim < 16)
+            imax = 45 + (5 * radio.RegOcp.bits.OcpTrim);
+        else if (radio.RegOcp.bits.OcpTrim < 28)
+            imax = -30 + (10 * radio.RegOcp.bits.OcpTrim);
+        else
+            imax = 240;
+        printf(" OcpOn %dmA ", imax);
+    } else
+        printf(" OcpOFF ");
+
+    printf("\r\n");
+
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+void lora_print_dio()
+{
+   radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
+    printf("DIO5:");
+    switch (radio.RegDioMapping2.bits.Dio5Mapping) {
+        case 0: printf("ModeReady"); break;
+        case 1: printf("ClkOut"); break;
+        case 2: printf("ClkOut"); break;
+    }
+    printf(" DIO4:");
+    switch (radio.RegDioMapping2.bits.Dio4Mapping) {
+        case 0: printf("CadDetected"); break;
+        case 1: printf("PllLock"); break;
+        case 2: printf("PllLock"); break;
+    }    
+    radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
+    printf(" DIO3:");
+    switch (radio.RegDioMapping1.bits.Dio3Mapping) {
+        case 0: printf("CadDone"); break;
+        case 1: printf("ValidHeader"); break;
+        case 2: printf("PayloadCrcError"); break;
+    }    
+    printf(" DIO2:");
+    switch (radio.RegDioMapping1.bits.Dio2Mapping) {
+        case 0:
+        case 1:
+        case 2:
+            printf("FhssChangeChannel");
+            break;
+    }    
+    printf(" DIO1:");
+    switch (radio.RegDioMapping1.bits.Dio1Mapping) {
+        case 0: printf("RxTimeout"); break;
+        case 1: printf("FhssChangeChannel"); break;
+        case 2: printf("CadDetected"); break;
+    }    
+    printf(" DIO0:");
+    switch (radio.RegDioMapping1.bits.Dio0Mapping) {
+        case 0: printf("RxDone"); break;
+        case 1: printf("TxDone"); break;
+        case 2: printf("CadDone"); break;
+    }    
+    
+    printf("\r\n"); 
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+void
+printCodingRate(bool from_rx)
+{
+    uint8_t d = radio.getCodingRate(from_rx);
+    printf("CodingRate:");
+    switch (d) {
+        case 1: printf("4/5 "); break;
+        case 2: printf("4/6 "); break;
+        case 3: printf("4/7 "); break;
+        case 4: printf("4/8 "); break;
+        default:
+            printf("%d ", d);
+            break;
+    }
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+void printHeaderMode()
+{
+    if (radio.getHeaderMode())
+        printf("implicit ");
+    else
+        printf("explicit ");
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+void printBw()
+{
+    uint8_t bw = radio.getBw();
+    
+    printf("Bw:");
+    if (radio.type == SX1276) {
+        switch (radio.RegModemConfig.sx1276bits.Bw) {
+            case 0: printf("7.8KHz "); break;
+            case 1: printf("10.4KHz "); break;
+            case 2: printf("15.6KHz "); break;
+            case 3: printf("20.8KHz "); break;
+            case 4: printf("31.25KHz "); break;
+            case 5: printf("41.7KHz "); break;
+            case 6: printf("62.5KHz "); break;
+            case 7: printf("125KHz "); break;
+            case 8: printf("250KHz "); break;
+            case 9: printf("500KHz "); break;
+            default: printf("%x ", radio.RegModemConfig.sx1276bits.Bw); break;
+        }
+    } else if (radio.type == SX1272) {
+        switch (radio.RegModemConfig.sx1272bits.Bw) {
+            case 0: printf("125KHz "); break;
+            case 1: printf("250KHz "); break;
+            case 2: printf("500KHz "); break;
+            case 3: printf("11b "); break;
+        }
+    }
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+void printSf()
+{
+    // spreading factor same between sx127[26]
+    printf("sf:%d ", radio.getSf());
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+void printTxContinuousMode()
+{
+    printf("TxContinuousMode:%d ", radio.RegModemConfig2.sx1276bits.TxContinuousMode);    // same for sx1272 and sx1276
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+void printAgcAutoOn()
+{
+    printf("AgcAutoOn:%d", radio.getAgcAutoOn());
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+void printRxPayloadCrcOn()
+{
+    bool on = radio.getRxPayloadCrcOn();
+    //printf("RxPayloadCrcOn:%s ", on ? "on" : "off");
+    if (on)
+        printf("RxPayloadCrcOn:1 = Tx CRC Enabled\r\n");
+    else
+        printf("RxPayloadCrcOn:1 = no Tx CRC\r\n");
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+void printLoraIrqs_(bool clear)
+{
+    //in radio class -- RegIrqFlags_t RegIrqFlags;
+
+    //already read RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
+    printf("\r\nIrqFlags:");
+    if (radio.RegIrqFlags.bits.CadDetected)
+        printf("CadDetected ");
+    if (radio.RegIrqFlags.bits.FhssChangeChannel) {
+        //radio.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL);
+        printf("FhssChangeChannel:%d ", radio.RegHopChannel.bits.FhssPresentChannel);
+    }
+    if (radio.RegIrqFlags.bits.CadDone)
+        printf("CadDone ");
+    if (radio.RegIrqFlags.bits.TxDone)
+        printf("TxDone ");
+    if (radio.RegIrqFlags.bits.ValidHeader)
+        printf("ValidHeader ");
+    if (radio.RegIrqFlags.bits.PayloadCrcError)
+        printf("PayloadCrcError ");
+    if (radio.RegIrqFlags.bits.RxDone)
+        printf("RxDone ");  
+    if (radio.RegIrqFlags.bits.RxTimeout)
+        printf("RxTimeout ");
+
+    printf("\r\n");
+
+    if (clear)
+        radio.write_reg(REG_LR_IRQFLAGS, radio.RegIrqFlags.octet);
+
+}
+#endif /* _DEBUG_ */
+
+#ifdef _DEBUG_
+void lora_print_status()
+{
+    uint8_t d;
+    
+    if (radio.type == SX1276)
+        printf("\r\nSX1276 ");
+    else if (radio.type == SX1272)
+        printf("\r\nSX1272 ");
+    
+    radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
+    if (!radio.RegOpMode.bits.LongRangeMode) {
+        printf("FSK\r\n");
+        return;
+    }
+    
+    lora_print_dio();
+    printf("LoRa ");
+    
+    // printing LoRa registers at 0x0d -> 0x3f
+
+    radio.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+    radio.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
+
+    printCodingRate(false); // false: transmitted coding rate
+    printHeaderMode();
+    printBw();
+    printSf();
+    printRxPayloadCrcOn();
+    // RegModemStat
+    printf("ModemStat:0x%02x\r\n", radio.read_reg(REG_LR_MODEMSTAT));
+
+    // fifo ptrs:
+    radio.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
+    radio.RegRxMaxPayloadLength = radio.read_reg(REG_LR_RX_MAX_PAYLOADLENGTH);
+    printf("fifoptr=0x%02x txbase=0x%02x rxbase=0x%02x payloadLength=0x%02x maxlen=0x%02x",
+        radio.read_reg(REG_LR_FIFOADDRPTR),
+        radio.read_reg(REG_LR_FIFOTXBASEADDR),
+        radio.read_reg(REG_LR_FIFORXBASEADDR),
+        radio.RegPayloadLength,
+        radio.RegRxMaxPayloadLength
+    );
+
+    radio.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
+    printLoraIrqs_(false);
+
+    radio.RegHopPeriod = radio.read_reg(REG_LR_HOPPERIOD);
+    if (radio.RegHopPeriod != 0) {
+        printf("\r\nHopPeriod:0x%02x\r\n", radio.RegHopPeriod);
+    }
+
+    printf("SymbTimeout:0x%03x ", radio.read_u16(REG_LR_MODEMCONFIG2) & 0x3ff);
+
+    radio.RegPreamble = radio.read_u16(REG_LR_PREAMBLEMSB);
+    printf("PreambleLength:0x%03x ", radio.RegPreamble);
+    
+
+    if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER_SINGLE) {
+        d = radio.read_reg(REG_LR_RSSIVALUE);
+        printf("rssi:%ddBm ", d-120);
+    }
+
+    printTxContinuousMode();
+
+    printf("\r\n");
+    printAgcAutoOn();
+    if (radio.type == SX1272) {
+        printf(" LowDataRateOptimize:%d\r\n", radio.RegModemConfig.sx1272bits.LowDataRateOptimize);
+    }
+
+    printf("\r\nHeaderCount:%d PacketCount:%d, ",
+        radio.read_u16(REG_LR_RXHEADERCNTVALUE_MSB), radio.read_u16(REG_LR_RXPACKETCNTVALUE_MSB));
+
+    printf("Lora detection threshold:%02x\r\n", radio.read_reg(REG_LR_DETECTION_THRESHOLD));
+    radio.RegTest31.octet = radio.read_reg(REG_LR_TEST31);
+    printf("detect_trig_same_peaks_nb:%d\r\n", radio.RegTest31.bits.detect_trig_same_peaks_nb);
+
+    if (radio.type == SX1272) {
+        radio.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+        printf("LowDataRateOptimize:%d\r\n", radio.RegModemConfig.sx1272bits.LowDataRateOptimize);
+    } else if (radio.type == SX1276) {
+        radio.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
+        printf("LowDataRateOptimize:%d\r\n", radio.RegModemConfig3.sx1276bits.LowDataRateOptimize);        
+    }
+    
+    printf("\r\n");
+    //printf("A %02x\r\n", radio.RegModemConfig2.octet);
+}
+#endif /* _DEBUG_ */
+
+void
+service_radio()
+{
+    service_action_e act = radio.service();
+    
+    switch (act) {
+        case SERVICE_READ_FIFO:
+            printf("SERVICE_READ_FIFO\r\n");
+            // clear Irq flags
+            radio.write_reg(REG_LR_IRQFLAGS, radio.RegIrqFlags.octet);        
+            break;
+        case SERVICE_TX_DONE:
+            printf("SERVICE_TX_DONE\r\n");
+            break;
+        case SERVICE_ERROR:
+            printf("error\r\n");
+            break;
+    } // ...switch (act)
+}
+        
+int
+main(void)
+{
+    #ifdef _DEBUG_ 
+    pc.baud(57600);
+    pc.printf("\r\nstart\r\n");
+    #endif /* _DEBUG_ */
+    
+    while (1) { 
+        //try to read a msg
+        if (hid.readNB(&recv_report)) {
+            HidCmdProcess();
+        }
+
+        #ifdef _DEBUG_   
+        if (pc.readable()) {
+            char c = pc.getc();
+            if (c == 'v') {
+                pc.printf("verbose ");
+                if (verbose) {
+                    verbose = 0;
+                    pc.printf("off");
+                } else {
+                    verbose = 1;
+                    pc.printf("on");
+                }
+                pc.printf("\r\n");
+            } else if (c == '.') {
+                common_print_status();
+                if (radio.RegOpMode.bits.LongRangeMode)
+                    lora_print_status();
+                else
+                    printf("FSK\r\n");
+            } else if (c == 't') {
+                int i;
+                printf("tx\r\n");
+                radio.set_opmode(RF_OPMODE_TRANSMITTER);
+                for (i = 0; i < 20; i++) {
+                    radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
+                    printf("opmode:%02x\r\n", radio.RegOpMode.octet);
+                }
+            } else if (c == 'T') {
+                printf("start_tx\r\n");
+                radio.RegPayloadLength = 8;
+                radio.write_reg(REG_LR_PAYLOADLENGTH, radio.RegPayloadLength);
+                radio.lora_start_tx(8);
+            } else if (c == 'e') {
+                printf("service_radio\r\n");
+                service_radio();
+            } else if (c == 's') {
+                radio.set_opmode(RF_OPMODE_STANDBY);
+                printf("standby\r\n");
+            } else if (c == 'h') {
+                printf("hwreset\r\n");
+                radio.hw_reset();
+                radio.init();   //SX1272Init( );
+            } else if (c == 'l') {
+                radio.SetLoRaOn(!radio.RegOpMode.bits.LongRangeMode);
+                printf("LongRangeMode:%d\r\n", radio.RegOpMode.bits.LongRangeMode);
+            } else if (c == '?') {
+                printf("s   standby\r\n");
+                printf("T   lora_start_tx(8)\r\n");
+                printf(".   print status\r\n");
+                printf("v   toggle verbose\r\n");
+                printf("t   tx mode test\r\n");
+                printf("e   manualy service radio once\r\n");
+                printf("h   hwreset, init\r\n");
+                printf("l   toggle lora mode\r\n");
+            }
+        } // ...if (pc.readable())
+        #endif /* _DEBUG_ */
+        
+    } // ...while (1)
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Apr 14 22:01:41 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/6473597d706e
\ No newline at end of file