Scan example on D7-LoRa

Dependencies:   modem_ref_helper DebouncedInterrupt

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // @autor: jeremie@wizzilab.com
00002 // @date: 2017-05-02
00003 
00004 #include "DebouncedInterrupt.h"
00005 #include "modem_d7a.h"
00006 #include "modem_callbacks.h"
00007 
00008 #if 1
00009     // Use D7 LoRa
00010     #define XCL_DL d7lora_dl_xcl
00011     #define XCL_UL d7lora_ul_xcl
00012 #else
00013     // Use D7 FSK
00014     #define XCL_DL d7fsk_dl_xcl
00015     #define XCL_UL d7fsk_ul_xcl
00016 #endif
00017 
00018 #if 0
00019     // Disable Duty Cycle
00020     #define DUTY 255
00021 #else
00022     // Use default Duty Cycle
00023     #define DUTY D7A_CTF_ENCODE(31)
00024 #endif
00025 
00026 Semaphore button_user(0);
00027 
00028 d7a_xcl_t d7fsk_dl_xcl = { .bf = { .m = 0x1, .s = 0 } };
00029 d7a_xcl_t d7fsk_ul_xcl = { .bf = { .m = 0x1, .s = 2 } };
00030 
00031 d7a_xcl_t d7lora_dl_xcl = { .bf = { .m = 0x1, .s = 8 } };
00032 d7a_xcl_t d7lora_ul_xcl = { .bf = { .m = 0x1, .s = 9 } };
00033 
00034 alp_d7a_itf_t my_itf = {
00035     .type                           = ALP_ITF_TYPE_D7A,
00036     .cfg.to.byte                    = D7A_CTF_ENCODE(0),
00037     .cfg.te.byte                    = D7A_CTF_ENCODE(0),
00038     .cfg.qos.bf.resp                = D7A_RESP_ALL,
00039     .cfg.qos.bf.retry               = ALP_RPOL_ONESHOT,
00040     .cfg.addressee.ctrl.bf.nls      = D7A_NLS_AES_CCM_64,
00041     .cfg.addressee.ctrl.bf.idf      = D7A_ID_NBID,
00042     .cfg.addressee.xcl              = XCL_UL,
00043     .cfg.addressee.id[0]            = D7A_CTF_ENCODE(4),
00044 };
00045 
00046 // Interrupt Service Routine on button press.
00047 void button_push_isr( void )
00048 {
00049     button_user.release();
00050 }
00051 
00052 void button_user_thread()
00053 {
00054     FPRINT("(id:0x%08x)\r\n", osThreadGetId());
00055 
00056     osEvent evt;
00057     fw_version_t fw_ver;
00058     uint8_t nb = 0;
00059     alp_payload_t* alp;
00060     alp_payload_t* alp_rsp;
00061     d7a_sp_res_t istat;
00062     int err;
00063         
00064     uint8_t scan_xcl[] = { XCL_DL.byte, XCL_UL.byte };
00065     
00066     modem_d7a_enable_itf();
00067     
00068     while (true)
00069     {
00070         // Wait for button press
00071         PRINT("Press button to scan...\r\n");
00072         button_user.acquire();
00073         
00074         for (uint8_t i = 0; i < sizeof(scan_xcl); i++)
00075         {
00076             nb = 0;
00077             my_itf.cfg.addressee.xcl.byte = scan_xcl[i];
00078             
00079             PRINT("Scanning XCL 0x%02X...\n", my_itf.cfg.addressee.xcl.byte);
00080             
00081             alp = NULL;
00082             alp = alp_payload_f_rd_data(alp, D7A_FID_FIRMWARE_VERSION, 12, sizeof(fw_version_t), false);
00083             
00084             err = modem_remote_raw_alp((void*)&my_itf, alp, &alp_rsp, (uint32_t)60000);
00085 
00086             if (err < ALP_ERR_NONE)
00087             {
00088                 PRINT("Timeout.\n");
00089             }
00090             else
00091             {
00092                 err = alp_payload_get_err(alp_rsp);
00093                 PRINT("Err %d: ", err);
00094                 modem_print_error(my_itf.type, err);
00095             }
00096             
00097             do {
00098                 nb++;
00099                 
00100                 alp = alp_payload_extract(&alp_rsp, ALP_OPCODE_RSP_ISTATUS);
00101 
00102                 if (alp)
00103                 {
00104                     alp_parsed_chunk_t r;
00105                     u8* p = alp->d;
00106                 
00107                     alp_parse_chunk(&p, &r);
00108                     memcpy(&istat, r.data, r.meta.itf.length);
00109                     
00110                     PRINT("%d: XCL:%02X ", nb, istat.addressee.xcl.byte);
00111                     PRINT_DATA("UID:", "%02X", istat.addressee.id, 8, " ");
00112                     PRINT("snr:%d rxlev:%d lb:%d ", istat.snr, istat.rxlev, istat.lb);
00113                     
00114                     alp_payload_free(alp);
00115                 }
00116                 else
00117                 {
00118                     break;
00119                 }
00120                 
00121                 alp = alp_payload_extract(&alp_rsp, ALP_OPCODE_RSP_F_DATA);
00122                 
00123                 if (alp)
00124                 {
00125                     alp_parsed_chunk_t r;
00126                     u8* p = alp->d;
00127                     
00128                     alp_parse_chunk(&p, &r);
00129                     memcpy(&fw_ver, r.data, r.meta.f_data.length);
00130                     
00131                     PRINT("v%d.%d.%d\n", fw_ver.major, fw_ver.minor, fw_ver.patch);
00132                     
00133                     alp_payload_free(alp);
00134                 }
00135                 else
00136                 {
00137                     break;
00138                 }
00139                 
00140                 FLUSH();
00141             } while (1);
00142             
00143             alp_payload_free(alp_rsp);
00144         }
00145         
00146         PRINT("Done.\n");
00147     }
00148 }
00149 
00150 modem_ref_callbacks_t callbacks = {
00151     .read       = my_read,
00152     .write      = my_write,
00153     .read_fprop = my_read_fprop,
00154     .flush      = my_flush,
00155     .remove     = my_delete,
00156     .udata      = my_udata,
00157     .lqual      = my_lqual,
00158     .ldown      = my_ldown,
00159     .reset      = my_reset,
00160     .boot       = my_boot
00161 };
00162 
00163 /*** Main function ------------------------------------------------------------- ***/
00164 int main()
00165 {
00166     // Start & initialize
00167 #ifdef DEBUG_LED
00168     DBG_OPEN(DEBUG_LED);
00169 #else
00170     DBG_OPEN(NC);
00171 #endif
00172     PRINT("\n"
00173           "-----------------------------------------\n"
00174           "------------- Demo D7A LoRa -------------\n"
00175           "-----------------------------------------\n");
00176           
00177     modem_open(&callbacks);
00178     
00179     // Put modem to listen to downlink access class
00180     modem_write_file(D7A_FID_DLL_CFG, &XCL_DL, offsetof(d7a_dll_cfg_t, xcl), sizeof(d7a_xcl_t));
00181     
00182     // Configure interface to use uplink access class
00183     modem_write_file(IFID_REPORT, &XCL_UL, offsetof(alp_d7a_itf_t, cfg.addressee.xcl), sizeof(d7a_xcl_t));
00184 
00185 #if 0
00186     // Configure duty
00187     d7a_ctf_t duty = { .byte = DUTY };
00188     for (int i = 0; i < 8; i++)
00189     {
00190         modem_write_file(D7A_FID_ACCESS_PROFILE_0 + XCL_DL.bf.s, &duty, offsetof(d7a_access_profile_t, sb[0].duty) + (i * sizeof(d7a_subband_t)), sizeof(d7a_ctf_t));
00191     }
00192     
00193     for (int i = 0; i < 8; i++)
00194     {
00195         modem_write_file(D7A_FID_ACCESS_PROFILE_0 + XCL_UL.bf.s, &duty, offsetof(d7a_access_profile_t, sb[0].duty) + (i * sizeof(d7a_subband_t)), sizeof(d7a_ctf_t));
00196     }
00197 #endif
00198 
00199 #ifdef DEBUG_BUTTON
00200     DebouncedInterrupt user_interrupt(DEBUG_BUTTON);
00201     user_interrupt.attach(button_push_isr, IRQ_FALL, 500, true);
00202     
00203     Thread but_th(osPriorityNormal, 2048, NULL);
00204     osStatus status = but_th.start(button_user_thread);
00205     ASSERT(status == osOK, "Failed to start but thread (err: %d)\r\n", status);
00206 #else
00207     #error You need a button to use this APP as is
00208 #endif
00209 
00210 #ifdef DEBUG_LED
00211     DigitalOut my_led(DEBUG_LED);
00212 #endif
00213     
00214     // Set main task to lowest priority
00215     osThreadSetPriority(osThreadGetId(), osPriorityLow);
00216     while(true)
00217     {
00218         ThisThread::sleep_for(500);
00219 #ifdef DEBUG_LED
00220         my_led = !my_led;
00221 #endif
00222     }
00223 }