Scan example on D7-LoRa

Dependencies:   modem_ref_helper DebouncedInterrupt

Committer:
Jeej
Date:
Thu Sep 20 08:36:34 2018 +0000
Revision:
2:de388004dca6
Parent:
1:27716ee59ca4
Child:
3:c1a36c817c48
Updated libraries and APP for modem v5.2+

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 0:6703784ff93e 1 // @autor: jeremie@wizzilab.com
Jeej 0:6703784ff93e 2 // @date: 2017-05-02
Jeej 0:6703784ff93e 3
Jeej 0:6703784ff93e 4 #include "DebouncedInterrupt.h"
Jeej 0:6703784ff93e 5 #include "modem_ref_helper.h"
Jeej 0:6703784ff93e 6 #include "modem_callbacks.h"
Jeej 0:6703784ff93e 7
Jeej 1:27716ee59ca4 8 #if 1
Jeej 1:27716ee59ca4 9 // Use D7 LoRa
Jeej 1:27716ee59ca4 10 #define XCL_DL d7lora_dl_xcl
Jeej 1:27716ee59ca4 11 #define XCL_UL d7lora_ul_xcl
Jeej 1:27716ee59ca4 12 #else
Jeej 1:27716ee59ca4 13 // Use D7 FSK
Jeej 1:27716ee59ca4 14 #define XCL_DL d7fsk_dl_xcl
Jeej 1:27716ee59ca4 15 #define XCL_UL d7fsk_ul_xcl
Jeej 1:27716ee59ca4 16 #endif
Jeej 1:27716ee59ca4 17
Jeej 1:27716ee59ca4 18 #if 1
Jeej 1:27716ee59ca4 19 // Disable Duty Cycle
Jeej 1:27716ee59ca4 20 #define DUTY 255
Jeej 1:27716ee59ca4 21 #else
Jeej 1:27716ee59ca4 22 // Use default Duty Cycle
Jeej 1:27716ee59ca4 23 #define DUTY D7A_CTF_ENCODE(31)
Jeej 1:27716ee59ca4 24 #endif
Jeej 1:27716ee59ca4 25
Jeej 0:6703784ff93e 26 #define MY_POLICY_IDX 0
Jeej 0:6703784ff93e 27
Jeej 0:6703784ff93e 28 Semaphore button_user(0);
Jeej 0:6703784ff93e 29 Semaphore modem_ready(0);
Jeej 0:6703784ff93e 30 Queue<void, 8> modem_resp;
Jeej 0:6703784ff93e 31
Jeej 0:6703784ff93e 32 enum {
Jeej 0:6703784ff93e 33 MODEM_RESP_NO,
Jeej 0:6703784ff93e 34 MODEM_RESP_TERMINAL,
Jeej 0:6703784ff93e 35 MODEM_RESP_DONE,
Jeej 0:6703784ff93e 36 };
Jeej 0:6703784ff93e 37
Jeej 1:27716ee59ca4 38 d7a_xcl_t d7fsk_dl_xcl = { .bf.s = 0, .bf.m = 1 };
Jeej 1:27716ee59ca4 39 d7a_xcl_t d7fsk_ul_xcl = { .bf.s = 2, .bf.m = 1 };
Jeej 1:27716ee59ca4 40
Jeej 1:27716ee59ca4 41 d7a_xcl_t d7lora_dl_xcl = { .bf.s = 8, .bf.m = 1 };
Jeej 1:27716ee59ca4 42 d7a_xcl_t d7lora_ul_xcl = { .bf.s = 9, .bf.m = 1 };
Jeej 1:27716ee59ca4 43
Jeej 0:6703784ff93e 44 alp_d7a_itf_t my_itf = {
Jeej 0:6703784ff93e 45 .type = ALP_ITF_TYPE_D7A,
Jeej 0:6703784ff93e 46 .cfg.to = 0,
Jeej 0:6703784ff93e 47 .cfg.te = 0,
Jeej 0:6703784ff93e 48 .cfg.qos.bf.resp = D7A_RESP_ALL,
Jeej 2:de388004dca6 49 .cfg.qos.bf.retry = ALP_RPOL_ONESHOT,
Jeej 0:6703784ff93e 50 .cfg.addressee.ctrl.bf.nls = D7A_NLS_AES_CCM_64,
Jeej 0:6703784ff93e 51 .cfg.addressee.ctrl.bf.idf = D7A_ID_NBID,
Jeej 1:27716ee59ca4 52 .cfg.addressee.xcl = XCL_UL,
Jeej 0:6703784ff93e 53 .cfg.addressee.id[0] = D7A_CTF_VAL(4,0),
Jeej 0:6703784ff93e 54 };
Jeej 0:6703784ff93e 55
Jeej 0:6703784ff93e 56 void print_status(int status)
Jeej 0:6703784ff93e 57 {
Jeej 0:6703784ff93e 58 switch (status)
Jeej 0:6703784ff93e 59 {
Jeej 0:6703784ff93e 60 case ALP_ERR_NONE:
Jeej 0:6703784ff93e 61 //PRINT("Status: OK\n");
Jeej 0:6703784ff93e 62 break;
Jeej 0:6703784ff93e 63 case ALP_ERR_FILE_EXIST:
Jeej 0:6703784ff93e 64 PRINT("Status: Already registered\n");
Jeej 0:6703784ff93e 65 break;
Jeej 0:6703784ff93e 66 default:
Jeej 0:6703784ff93e 67 PRINT("Status: error %d\n", status);
Jeej 0:6703784ff93e 68 break;
Jeej 0:6703784ff93e 69 }
Jeej 0:6703784ff93e 70 }
Jeej 0:6703784ff93e 71
Jeej 0:6703784ff93e 72 void print_resp(int status)
Jeej 0:6703784ff93e 73 {
Jeej 0:6703784ff93e 74 switch (status)
Jeej 0:6703784ff93e 75 {
Jeej 0:6703784ff93e 76 case ALP_ERR_NONE:
Jeej 0:6703784ff93e 77 //PRINT("Resp: OK\n");
Jeej 0:6703784ff93e 78 break;
Jeej 0:6703784ff93e 79 case ALP_ERR_FILE_EXIST:
Jeej 0:6703784ff93e 80 PRINT("Resp: Already registered\n");
Jeej 0:6703784ff93e 81 break;
Jeej 0:6703784ff93e 82 default:
Jeej 0:6703784ff93e 83 PRINT("Resp: error %d\n", status);
Jeej 0:6703784ff93e 84 break;
Jeej 0:6703784ff93e 85 }
Jeej 0:6703784ff93e 86 }
Jeej 0:6703784ff93e 87
Jeej 0:6703784ff93e 88 // Callback for broadcast read
Jeej 0:6703784ff93e 89 void my_read_response_callback(uint8_t terminal, int8_t err, uint8_t id)
Jeej 0:6703784ff93e 90 {
Jeej 0:6703784ff93e 91 (void)id;
Jeej 0:6703784ff93e 92
Jeej 0:6703784ff93e 93 if (terminal)
Jeej 0:6703784ff93e 94 {
Jeej 0:6703784ff93e 95 print_status(err);
Jeej 0:6703784ff93e 96 modem_resp.put((void*)MODEM_RESP_TERMINAL);
Jeej 0:6703784ff93e 97 }
Jeej 0:6703784ff93e 98 else
Jeej 0:6703784ff93e 99 {
Jeej 0:6703784ff93e 100 print_resp(err);
Jeej 0:6703784ff93e 101 if (ALP_ERR_NONE == err)
Jeej 0:6703784ff93e 102 {
Jeej 0:6703784ff93e 103 modem_resp.put((void*)MODEM_RESP_DONE);
Jeej 0:6703784ff93e 104 }
Jeej 0:6703784ff93e 105 }
Jeej 0:6703784ff93e 106 }
Jeej 0:6703784ff93e 107
Jeej 0:6703784ff93e 108 // Interrupt Service Routine on button press.
Jeej 0:6703784ff93e 109 void button_push_isr( void )
Jeej 0:6703784ff93e 110 {
Jeej 0:6703784ff93e 111 button_user.release();
Jeej 0:6703784ff93e 112 }
Jeej 0:6703784ff93e 113
Jeej 0:6703784ff93e 114 void button_user_thread()
Jeej 0:6703784ff93e 115 {
Jeej 0:6703784ff93e 116 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:6703784ff93e 117
Jeej 0:6703784ff93e 118 osEvent evt;
Jeej 0:6703784ff93e 119 uint32_t resp;
Jeej 0:6703784ff93e 120 d7a_sp_res_t istat;
Jeej 0:6703784ff93e 121 fw_version_t fw_ver;
Jeej 0:6703784ff93e 122 uint8_t nb = 0;
Jeej 0:6703784ff93e 123
Jeej 2:de388004dca6 124 uint8_t id = modem_get_id(my_read_response_callback);
Jeej 0:6703784ff93e 125
Jeej 1:27716ee59ca4 126 uint8_t scan_xcl[] = { XCL_DL.byte, XCL_UL.byte };
Jeej 0:6703784ff93e 127
Jeej 0:6703784ff93e 128 memset(&istat, 0, sizeof(d7a_sp_res_t));
Jeej 0:6703784ff93e 129 memset(&fw_ver, 0, sizeof(fw_version_t));
Jeej 0:6703784ff93e 130
Jeej 0:6703784ff93e 131 while (true)
Jeej 0:6703784ff93e 132 {
Jeej 0:6703784ff93e 133 // Wait for button press
Jeej 0:6703784ff93e 134 PRINT("Press button to scan...\r\n");
Jeej 0:6703784ff93e 135 button_user.wait();
Jeej 0:6703784ff93e 136
Jeej 0:6703784ff93e 137 for (uint8_t i = 0; i < sizeof(scan_xcl); i++)
Jeej 0:6703784ff93e 138 {
Jeej 0:6703784ff93e 139 nb = 0;
Jeej 0:6703784ff93e 140 my_itf.cfg.addressee.xcl.byte = scan_xcl[i];
Jeej 0:6703784ff93e 141
Jeej 0:6703784ff93e 142 PRINT("Scanning XCL 0x%02X...\n", my_itf.cfg.addressee.xcl.byte);
Jeej 0:6703784ff93e 143
Jeej 2:de388004dca6 144 modem_remote_read_file((uint8_t*)&my_itf, D7_ITF_SIZE(&my_itf), (void*)&istat, D7A_FID_FIRMWARE_VERSION, (void*)&fw_ver, 12, sizeof(fw_version_t), id);
Jeej 0:6703784ff93e 145
Jeej 0:6703784ff93e 146 do
Jeej 0:6703784ff93e 147 {
Jeej 0:6703784ff93e 148 evt = modem_resp.get();
Jeej 0:6703784ff93e 149 resp = (evt.status == osEventMessage)? (uint32_t)evt.value.p : MODEM_RESP_NO;
Jeej 0:6703784ff93e 150
Jeej 0:6703784ff93e 151 if (MODEM_RESP_DONE == resp)
Jeej 0:6703784ff93e 152 {
Jeej 0:6703784ff93e 153 nb++;
Jeej 0:6703784ff93e 154 PRINT("%d: XCL:%02X ", nb, istat.addressee.xcl.byte);
Jeej 0:6703784ff93e 155 PRINT_DATA("UID:", "%02X", istat.addressee.id, 8, " ");
Jeej 0:6703784ff93e 156 PRINT("snr:%d rxlev:%d lb:%d ", istat.snr, istat.rxlev, istat.lb);
Jeej 0:6703784ff93e 157 PRINT("v%d.%d.%d\n", fw_ver.major, fw_ver.minor, fw_ver.patch);
Jeej 0:6703784ff93e 158
Jeej 0:6703784ff93e 159 // Reset variables
Jeej 0:6703784ff93e 160 memset(&istat, 0, sizeof(d7a_sp_res_t));
Jeej 0:6703784ff93e 161 memset(&fw_ver, 0, sizeof(fw_version_t));
Jeej 0:6703784ff93e 162 }
Jeej 0:6703784ff93e 163
Jeej 0:6703784ff93e 164 } while (MODEM_RESP_TERMINAL != resp);
Jeej 0:6703784ff93e 165 }
Jeej 0:6703784ff93e 166
Jeej 0:6703784ff93e 167 PRINT("Done.\n");
Jeej 0:6703784ff93e 168 }
Jeej 0:6703784ff93e 169 }
Jeej 0:6703784ff93e 170
Jeej 0:6703784ff93e 171 modem_callbacks_t callbacks = {
Jeej 0:6703784ff93e 172 .read = my_read,
Jeej 0:6703784ff93e 173 .write = my_write,
Jeej 0:6703784ff93e 174 .read_fprop = my_read_fprop,
Jeej 0:6703784ff93e 175 .flush = my_flush,
Jeej 0:6703784ff93e 176 .remove = my_delete,
Jeej 0:6703784ff93e 177 .udata = my_udata,
Jeej 0:6703784ff93e 178 .lqual = my_lqual,
Jeej 0:6703784ff93e 179 .ldown = my_ldown,
Jeej 0:6703784ff93e 180 .reset = my_reset,
Jeej 0:6703784ff93e 181 .boot = my_boot
Jeej 0:6703784ff93e 182 };
Jeej 0:6703784ff93e 183
Jeej 2:de388004dca6 184 // Callback for id User
Jeej 0:6703784ff93e 185 void my_main_callback(uint8_t terminal, int8_t err, uint8_t id)
Jeej 0:6703784ff93e 186 {
Jeej 0:6703784ff93e 187 (void)id;
Jeej 0:6703784ff93e 188
Jeej 0:6703784ff93e 189 if (terminal)
Jeej 0:6703784ff93e 190 {
Jeej 0:6703784ff93e 191 print_status(err);
Jeej 0:6703784ff93e 192 modem_ready.release();
Jeej 0:6703784ff93e 193 }
Jeej 0:6703784ff93e 194 else
Jeej 0:6703784ff93e 195 {
Jeej 0:6703784ff93e 196 print_resp(err);
Jeej 0:6703784ff93e 197 }
Jeej 0:6703784ff93e 198 }
Jeej 0:6703784ff93e 199
Jeej 0:6703784ff93e 200 /*** Main function ------------------------------------------------------------- ***/
Jeej 0:6703784ff93e 201 int main()
Jeej 0:6703784ff93e 202 {
Jeej 0:6703784ff93e 203 // Start & initialize
Jeej 0:6703784ff93e 204 #ifdef DEBUG_LED
Jeej 0:6703784ff93e 205 DBG_OPEN(DEBUG_LED);
Jeej 0:6703784ff93e 206 #else
Jeej 0:6703784ff93e 207 DBG_OPEN(NC);
Jeej 0:6703784ff93e 208 #endif
Jeej 0:6703784ff93e 209 PRINT("\n"
Jeej 0:6703784ff93e 210 "-----------------------------------------\n"
Jeej 1:27716ee59ca4 211 "-------------- Demo D7A LoRa ------------\n"
Jeej 0:6703784ff93e 212 "-----------------------------------------\n");
Jeej 0:6703784ff93e 213
Jeej 0:6703784ff93e 214 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:6703784ff93e 215
Jeej 0:6703784ff93e 216 modem_helper_open(&callbacks);
Jeej 0:6703784ff93e 217
Jeej 2:de388004dca6 218 uint8_t id = modem_get_id(my_main_callback);
Jeej 0:6703784ff93e 219
Jeej 1:27716ee59ca4 220 // Put modem to listen to downlink access class
Jeej 2:de388004dca6 221 modem_write_file(D7A_FID_DLL_CFG, &XCL_DL, offsetof(d7a_dll_cfg_t, xcl), sizeof(d7a_xcl_t), id);
Jeej 1:27716ee59ca4 222 modem_ready.wait();
Jeej 1:27716ee59ca4 223
Jeej 1:27716ee59ca4 224 // Configure interfaces to use uplink access class
Jeej 2:de388004dca6 225 modem_write_file(IFID_ONESHOT_HOST, &XCL_UL, offsetof(alp_d7a_itf_t, cfg.addressee.xcl), sizeof(d7a_xcl_t), id);
Jeej 1:27716ee59ca4 226 modem_ready.wait();
Jeej 1:27716ee59ca4 227
Jeej 2:de388004dca6 228 modem_write_file(IFID_ONESHOT_ACTP, &XCL_UL, offsetof(alp_d7a_itf_t, cfg.addressee.xcl), sizeof(d7a_xcl_t), id);
Jeej 1:27716ee59ca4 229 modem_ready.wait();
Jeej 1:27716ee59ca4 230
Jeej 2:de388004dca6 231 modem_write_file(IFID_REPORT, &XCL_UL, offsetof(alp_d7a_itf_t, cfg.addressee.xcl), sizeof(d7a_xcl_t), id);
Jeej 1:27716ee59ca4 232 modem_ready.wait();
Jeej 1:27716ee59ca4 233
Jeej 1:27716ee59ca4 234 // Configure duty
Jeej 1:27716ee59ca4 235 d7a_ctf_t duty = { .byte = DUTY };
Jeej 1:27716ee59ca4 236 for (int i = 0; i < 8; i++)
Jeej 1:27716ee59ca4 237 {
Jeej 2:de388004dca6 238 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), id);
Jeej 1:27716ee59ca4 239 modem_ready.wait();
Jeej 1:27716ee59ca4 240 }
Jeej 1:27716ee59ca4 241
Jeej 1:27716ee59ca4 242 for (int i = 0; i < 8; i++)
Jeej 1:27716ee59ca4 243 {
Jeej 2:de388004dca6 244 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), id);
Jeej 1:27716ee59ca4 245 modem_ready.wait();
Jeej 1:27716ee59ca4 246 }
Jeej 1:27716ee59ca4 247
Jeej 0:6703784ff93e 248 PRINT("Start D7A Stack\n");
Jeej 2:de388004dca6 249 modem_activate_itf(ALP_ITF_TYPE_D7A, 24, 0, ALP_D7A_ISTAT_RESP | ALP_D7A_ISTAT_UNS, true, id);
Jeej 0:6703784ff93e 250 modem_ready.wait();
Jeej 2:de388004dca6 251
Jeej 2:de388004dca6 252 modem_free_id(id);
Jeej 0:6703784ff93e 253
Jeej 0:6703784ff93e 254 #ifdef DEBUG_BUTTON
Jeej 0:6703784ff93e 255 DebouncedInterrupt user_interrupt(DEBUG_BUTTON);
Jeej 0:6703784ff93e 256 user_interrupt.attach(button_push_isr, IRQ_FALL, 500, true);
Jeej 0:6703784ff93e 257
Jeej 0:6703784ff93e 258 Thread but_th(osPriorityNormal, 2048, NULL);
Jeej 0:6703784ff93e 259 osStatus status = but_th.start(button_user_thread);
Jeej 0:6703784ff93e 260 ASSERT(status == osOK, "Failed to start but thread (err: %d)\r\n", status);
Jeej 0:6703784ff93e 261 #else
Jeej 0:6703784ff93e 262 #error You need a button to use this APP as is
Jeej 0:6703784ff93e 263 #endif
Jeej 0:6703784ff93e 264
Jeej 0:6703784ff93e 265 #ifdef DEBUG_LED
Jeej 0:6703784ff93e 266 DigitalOut my_led(DEBUG_LED);
Jeej 0:6703784ff93e 267 #endif
Jeej 0:6703784ff93e 268
Jeej 0:6703784ff93e 269 // Set main task to lowest priority
Jeej 0:6703784ff93e 270 osThreadSetPriority(osThreadGetId(), osPriorityIdle);
Jeej 0:6703784ff93e 271 while(true)
Jeej 0:6703784ff93e 272 {
Jeej 0:6703784ff93e 273 Thread::wait(500);
Jeej 0:6703784ff93e 274 #ifdef DEBUG_LED
Jeej 0:6703784ff93e 275 my_led = !my_led;
Jeej 0:6703784ff93e 276 #endif
Jeej 0:6703784ff93e 277 }
Jeej 0:6703784ff93e 278 }