Ping pong app demo.

Dependencies:   modem_ref_helper DebouncedInterrupt

Committer:
Jeej
Date:
Mon Mar 05 09:56:30 2018 +0000
Revision:
6:287a9759d70a
Parent:
3:0979d8cba5ec
Child:
7:7524fab147aa
Updated for 5.0.x

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 0:fa3fd69f8148 1 // @autor: jeremie@wizzilab.com
Jeej 0:fa3fd69f8148 2 // @date: 2017-05-02
Jeej 0:fa3fd69f8148 3
Jeej 0:fa3fd69f8148 4 #include "DebouncedInterrupt.h"
Jeej 2:785b422c7d22 5 #include "modem_ref_helper.h"
Jeej 0:fa3fd69f8148 6 #include "modem_callbacks.h"
Jeej 0:fa3fd69f8148 7
Jeej 0:fa3fd69f8148 8 Semaphore button_user(0);
Jeej 0:fa3fd69f8148 9 Semaphore modem_ready[MAX_USER_NB];
Jeej 0:fa3fd69f8148 10
Jeej 0:fa3fd69f8148 11 enum {
Jeej 0:fa3fd69f8148 12 MODEM_RESP_NO,
Jeej 0:fa3fd69f8148 13 MODEM_RESP_TERMINAL,
Jeej 0:fa3fd69f8148 14 MODEM_RESP_DONE,
Jeej 0:fa3fd69f8148 15 };
Jeej 0:fa3fd69f8148 16
Jeej 0:fa3fd69f8148 17 uint8_t g_main_id;
Jeej 0:fa3fd69f8148 18 uint8_t g_void_id;
Jeej 0:fa3fd69f8148 19
Jeej 0:fa3fd69f8148 20 typedef struct {
Jeej 0:fa3fd69f8148 21 Thread* thread;
Jeej 0:fa3fd69f8148 22 uint32_t count;
Jeej 0:fa3fd69f8148 23 d7a_addressee_t addressee;
Jeej 0:fa3fd69f8148 24 } ping_t;
Jeej 0:fa3fd69f8148 25
Jeej 0:fa3fd69f8148 26
Jeej 0:fa3fd69f8148 27 #define MY_POLICY_IDX 0
Jeej 0:fa3fd69f8148 28 #define FID_PING_PONG 128
Jeej 3:0979d8cba5ec 29 #define PING_DELAY 1000
Jeej 0:fa3fd69f8148 30 #define PING_COUNTER_SIZE sizeof(uint32_t)
Jeej 0:fa3fd69f8148 31 #define MAX_PING_NB MAX_USER_NB-2
Jeej 0:fa3fd69f8148 32
Jeej 3:0979d8cba5ec 33 // Special access classes for tests: no duty cycle limit, continuous scan
Jeej 3:0979d8cba5ec 34 // { .bf.s = 12, .bf.m = 1 }; --> High Rate
Jeej 3:0979d8cba5ec 35 // { .bf.s = 13, .bf.m = 1 }; --> Normal Rate
Jeej 3:0979d8cba5ec 36 // { .bf.s = 14, .bf.m = 1 }; --> Slow Rate
Jeej 3:0979d8cba5ec 37
Jeej 3:0979d8cba5ec 38 // We use these access class in this test, because in a normal access class,
Jeej 6:287a9759d70a 39 // the transmission will be stopped by the duty cycle limit after several PINGs.
Jeej 0:fa3fd69f8148 40 d7a_xcl_t ping_pong_xcl = { .bf.s = 13, .bf.m = 1 };
Jeej 0:fa3fd69f8148 41
Jeej 6:287a9759d70a 42 // This discribes the retry policy of the stack for each packet
Jeej 6:287a9759d70a 43 // Do not modify uncommented parameters
Jeej 0:fa3fd69f8148 44 alp_retry_policy_t my_policy = {
Jeej 0:fa3fd69f8148 45 .meta.procedure = 0,
Jeej 0:fa3fd69f8148 46 .meta.respond = true,
Jeej 0:fa3fd69f8148 47 .meta.persistant = false,
Jeej 0:fa3fd69f8148 48 .meta.bulk = false,
Jeej 0:fa3fd69f8148 49 .depth = 1,
Jeej 6:287a9759d70a 50 .retries = 0, // The stack will retry x times (each packet will be sent a maximum of x+1 times)
Jeej 6:287a9759d70a 51 .slot_time = 0 // Interval between retries in seconds
Jeej 0:fa3fd69f8148 52 };
Jeej 0:fa3fd69f8148 53
Jeej 6:287a9759d70a 54
Jeej 6:287a9759d70a 55 // This describe the interface used for communication
Jeej 6:287a9759d70a 56 // Do not modify uncommented parameters
Jeej 0:fa3fd69f8148 57 alp_d7a_itf_t my_itf = {
Jeej 0:fa3fd69f8148 58 .type = ALP_ITF_TYPE_D7A,
Jeej 0:fa3fd69f8148 59 .cfg.to = 0,
Jeej 0:fa3fd69f8148 60 .cfg.te = 0,
Jeej 6:287a9759d70a 61 .cfg.qos.bf.resp = D7A_RESP_NO, // Communication protocol
Jeej 6:287a9759d70a 62 .cfg.qos.bf.retry = MY_POLICY_IDX, // Retry policy
Jeej 6:287a9759d70a 63 .cfg.addressee.ctrl.bf.nls = D7A_NLS_AES_CCM_64, // Security level
Jeej 6:287a9759d70a 64 .cfg.addressee.xcl = ping_pong_xcl, // Used Access Class
Jeej 6:287a9759d70a 65 // One of the followings:
Jeej 6:287a9759d70a 66 .cfg.addressee.ctrl.bf.idf = D7A_ID_NOID, // No response
Jeej 6:287a9759d70a 67
Jeej 6:287a9759d70a 68 //.cfg.addressee.ctrl.bf.idf = D7A_ID_UID, // in Unicast
Jeej 6:287a9759d70a 69 //.cfg.addressee.id = { 0x00, 0x1B, 0xC5, 0x0C, 0x70, 0x00, 0x00, 0x00 }, // Destination UID
Jeej 6:287a9759d70a 70
Jeej 6:287a9759d70a 71 //.cfg.addressee.ctrl.bf.idf = D7A_ID_NBID, // in Broadcast
Jeej 6:287a9759d70a 72 //.cfg.addressee.id[0] = 4, // Estimation of reachable devices (2 to 32)
Jeej 0:fa3fd69f8148 73 };
Jeej 0:fa3fd69f8148 74
Jeej 0:fa3fd69f8148 75 void print_status(int status)
Jeej 0:fa3fd69f8148 76 {
Jeej 0:fa3fd69f8148 77 switch (status)
Jeej 0:fa3fd69f8148 78 {
Jeej 0:fa3fd69f8148 79 case ALP_ERR_NONE:
Jeej 3:0979d8cba5ec 80 //PRINT("Status: OK\n");
Jeej 0:fa3fd69f8148 81 break;
Jeej 0:fa3fd69f8148 82 case ALP_ERR_FILE_EXIST:
Jeej 0:fa3fd69f8148 83 PRINT("Status: Already registered\n");
Jeej 0:fa3fd69f8148 84 break;
Jeej 0:fa3fd69f8148 85 default:
Jeej 0:fa3fd69f8148 86 PRINT("Status: error %d\n", status);
Jeej 0:fa3fd69f8148 87 break;
Jeej 0:fa3fd69f8148 88 }
Jeej 0:fa3fd69f8148 89 }
Jeej 0:fa3fd69f8148 90
Jeej 0:fa3fd69f8148 91 void print_resp(int status)
Jeej 0:fa3fd69f8148 92 {
Jeej 0:fa3fd69f8148 93 switch (status)
Jeej 0:fa3fd69f8148 94 {
Jeej 0:fa3fd69f8148 95 case ALP_ERR_NONE:
Jeej 3:0979d8cba5ec 96 //PRINT("Resp: OK\n");
Jeej 0:fa3fd69f8148 97 break;
Jeej 0:fa3fd69f8148 98 case ALP_ERR_FILE_EXIST:
Jeej 0:fa3fd69f8148 99 PRINT("Resp: Already registered\n");
Jeej 0:fa3fd69f8148 100 break;
Jeej 0:fa3fd69f8148 101 default:
Jeej 0:fa3fd69f8148 102 PRINT("Resp: error %d\n", status);
Jeej 0:fa3fd69f8148 103 break;
Jeej 0:fa3fd69f8148 104 }
Jeej 0:fa3fd69f8148 105 }
Jeej 0:fa3fd69f8148 106
Jeej 0:fa3fd69f8148 107 // Callback for User
Jeej 0:fa3fd69f8148 108 void my_main_callback(uint8_t terminal, int8_t err, uint8_t id)
Jeej 0:fa3fd69f8148 109 {
Jeej 0:fa3fd69f8148 110 (void)id;
Jeej 0:fa3fd69f8148 111
Jeej 0:fa3fd69f8148 112 if (terminal)
Jeej 0:fa3fd69f8148 113 {
Jeej 0:fa3fd69f8148 114 print_status(err);
Jeej 0:fa3fd69f8148 115 modem_ready[id].release();
Jeej 0:fa3fd69f8148 116 }
Jeej 0:fa3fd69f8148 117 else
Jeej 0:fa3fd69f8148 118 {
Jeej 0:fa3fd69f8148 119 print_resp(err);
Jeej 0:fa3fd69f8148 120 }
Jeej 0:fa3fd69f8148 121 }
Jeej 0:fa3fd69f8148 122
Jeej 0:fa3fd69f8148 123 void my_void_callback(uint8_t terminal, int8_t err, uint8_t id)
Jeej 0:fa3fd69f8148 124 {
Jeej 0:fa3fd69f8148 125 (void)terminal;
Jeej 0:fa3fd69f8148 126 (void)id;
Jeej 0:fa3fd69f8148 127 print_status(err);
Jeej 0:fa3fd69f8148 128 }
Jeej 0:fa3fd69f8148 129
Jeej 0:fa3fd69f8148 130
Jeej 0:fa3fd69f8148 131 // Interrupt Service Routine on button press.
Jeej 0:fa3fd69f8148 132 void button_push_isr( void )
Jeej 0:fa3fd69f8148 133 {
Jeej 0:fa3fd69f8148 134 button_user.release();
Jeej 0:fa3fd69f8148 135 }
Jeej 0:fa3fd69f8148 136
Jeej 2:785b422c7d22 137 #ifdef DEBUG_LED
Jeej 0:fa3fd69f8148 138 DigitalOut my_led(DEBUG_LED);
Jeej 0:fa3fd69f8148 139 #endif
Jeej 0:fa3fd69f8148 140
Jeej 3:0979d8cba5ec 141 void my_udata(u8 fid, void *data, u32 offset, u32 length, u8 i_type, u8 i_length, u8* i_data)
Jeej 0:fa3fd69f8148 142 {
Jeej 0:fa3fd69f8148 143 (void)data;
Jeej 0:fa3fd69f8148 144 (void)i_length;
Jeej 0:fa3fd69f8148 145
Jeej 3:0979d8cba5ec 146 if (i_type == ALP_ITF_TYPE_D7A)
Jeej 0:fa3fd69f8148 147 {
Jeej 6:287a9759d70a 148 d7a_sp_res_t istat;
Jeej 6:287a9759d70a 149
Jeej 6:287a9759d70a 150 // Get interface status
Jeej 6:287a9759d70a 151 memcpy(&istat, i_data, i_length);
Jeej 3:0979d8cba5ec 152
Jeej 6:287a9759d70a 153 if(FID_PING_PONG == fid && 0 == offset && PING_COUNTER_SIZE == length)
Jeej 6:287a9759d70a 154 {
Jeej 6:287a9759d70a 155 uint32_t count;
Jeej 6:287a9759d70a 156
Jeej 6:287a9759d70a 157 // Get data
Jeej 6:287a9759d70a 158 memcpy(&count, data, length);
Jeej 3:0979d8cba5ec 159
Jeej 6:287a9759d70a 160 PRINT("Got PING %d", count);
Jeej 6:287a9759d70a 161 PRINT_DATA(" from ", "%02X", istat.addressee.id, 8, "");
Jeej 6:287a9759d70a 162 PRINT(" (SNR:%d dB RXLEV:%d dBm LB:%d dB)\n", istat.snr, -istat.rxlev, istat.lb);
Jeej 6:287a9759d70a 163
Jeej 6:287a9759d70a 164 #ifdef DEBUG_LED
Jeej 3:0979d8cba5ec 165 my_led = 1;
Jeej 6:287a9759d70a 166 #endif
Jeej 0:fa3fd69f8148 167
Jeej 3:0979d8cba5ec 168 Thread::wait(PING_DELAY);
Jeej 3:0979d8cba5ec 169
Jeej 6:287a9759d70a 170 #ifdef DEBUG_LED
Jeej 3:0979d8cba5ec 171 my_led = 0;
Jeej 6:287a9759d70a 172 #endif
Jeej 3:0979d8cba5ec 173
Jeej 3:0979d8cba5ec 174 alp_d7a_itf_t resp_itf = {
Jeej 3:0979d8cba5ec 175 .type = ALP_ITF_TYPE_D7A,
Jeej 3:0979d8cba5ec 176 .cfg.to = 0,
Jeej 3:0979d8cba5ec 177 .cfg.te = 0,
Jeej 3:0979d8cba5ec 178 .cfg.qos.bf.resp = D7A_RESP_NO,
Jeej 3:0979d8cba5ec 179 .cfg.qos.bf.retry = MY_POLICY_IDX,
Jeej 6:287a9759d70a 180 .cfg.addressee = istat.addressee,
Jeej 3:0979d8cba5ec 181 };
Jeej 3:0979d8cba5ec 182
Jeej 6:287a9759d70a 183 count++;
Jeej 3:0979d8cba5ec 184
Jeej 3:0979d8cba5ec 185 // Send ping
Jeej 6:287a9759d70a 186 PRINT("Send PING %d", count);
Jeej 3:0979d8cba5ec 187 PRINT_DATA(" to ", "%02X", resp_itf.cfg.addressee.id, 8, "\n");
Jeej 3:0979d8cba5ec 188
Jeej 6:287a9759d70a 189 modem_send_file_content((uint8_t*)&resp_itf, D7_ITF_SIZE(&resp_itf), NULL, FID_PING_PONG, &count, 0, PING_COUNTER_SIZE, g_void_id);
Jeej 3:0979d8cba5ec 190 }
Jeej 0:fa3fd69f8148 191 }
Jeej 0:fa3fd69f8148 192 }
Jeej 0:fa3fd69f8148 193
Jeej 0:fa3fd69f8148 194 void button_user_thread()
Jeej 0:fa3fd69f8148 195 {
Jeej 0:fa3fd69f8148 196 d7a_sp_res_t istat;
Jeej 0:fa3fd69f8148 197 uint32_t ping = 0;
Jeej 0:fa3fd69f8148 198
Jeej 0:fa3fd69f8148 199 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:fa3fd69f8148 200
Jeej 0:fa3fd69f8148 201 while (true)
Jeej 0:fa3fd69f8148 202 {
Jeej 0:fa3fd69f8148 203 // Wait for button press
Jeej 3:0979d8cba5ec 204 PRINT("PRESS BUTTON TO INITIATE PING...\n");
Jeej 0:fa3fd69f8148 205 button_user.wait();
Jeej 0:fa3fd69f8148 206
Jeej 0:fa3fd69f8148 207 // Initiate ping
Jeej 0:fa3fd69f8148 208 PRINT("Initiate PING\n");
Jeej 2:785b422c7d22 209 modem_send_file_content((uint8_t*)&my_itf, D7_ITF_SIZE(&my_itf), (void*)&istat, FID_PING_PONG, &ping, 0, PING_COUNTER_SIZE, g_main_id);
Jeej 0:fa3fd69f8148 210 modem_ready[g_main_id].wait();
Jeej 0:fa3fd69f8148 211 }
Jeej 0:fa3fd69f8148 212 }
Jeej 0:fa3fd69f8148 213
Jeej 0:fa3fd69f8148 214 modem_callbacks_t callbacks = {
Jeej 0:fa3fd69f8148 215 .read = my_read,
Jeej 0:fa3fd69f8148 216 .write = my_write,
Jeej 0:fa3fd69f8148 217 .read_fprop = my_read_fprop,
Jeej 0:fa3fd69f8148 218 .flush = my_flush,
Jeej 0:fa3fd69f8148 219 .remove = my_delete,
Jeej 0:fa3fd69f8148 220 .udata = my_udata,
Jeej 0:fa3fd69f8148 221 .lqual = my_lqual,
Jeej 0:fa3fd69f8148 222 .ldown = my_ldown,
Jeej 0:fa3fd69f8148 223 .reset = my_reset,
Jeej 0:fa3fd69f8148 224 .boot = my_boot
Jeej 0:fa3fd69f8148 225 };
Jeej 0:fa3fd69f8148 226
Jeej 0:fa3fd69f8148 227 /*** Main function ------------------------------------------------------------- ***/
Jeej 0:fa3fd69f8148 228 int main()
Jeej 0:fa3fd69f8148 229 {
Jeej 0:fa3fd69f8148 230 // Start & initialize
Jeej 2:785b422c7d22 231 #ifdef DEBUG_LED
Jeej 0:fa3fd69f8148 232 DBG_OPEN(DEBUG_LED);
Jeej 2:785b422c7d22 233 #else
Jeej 2:785b422c7d22 234 DBG_OPEN(NC);
Jeej 2:785b422c7d22 235 #endif
Jeej 3:0979d8cba5ec 236 PRINT("\n"
Jeej 3:0979d8cba5ec 237 "-----------------------------------------\n"
Jeej 3:0979d8cba5ec 238 "------------ Demo Ping Pong -------------\n"
Jeej 3:0979d8cba5ec 239 "-----------------------------------------\n");
Jeej 3:0979d8cba5ec 240
Jeej 0:fa3fd69f8148 241 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:fa3fd69f8148 242
Jeej 2:785b422c7d22 243 modem_helper_open(&callbacks);
Jeej 0:fa3fd69f8148 244
Jeej 0:fa3fd69f8148 245 g_main_id = modem_get_id(my_main_callback);
Jeej 1:4629ccf8315d 246
Jeej 0:fa3fd69f8148 247 // Put modem to listen to this access class
Jeej 0:fa3fd69f8148 248 modem_write_file(D7A_FID_DLL_CFG, &ping_pong_xcl, 0, sizeof(d7a_xcl_t), g_main_id);
Jeej 0:fa3fd69f8148 249 modem_ready[g_main_id].wait();
Jeej 0:fa3fd69f8148 250
Jeej 6:287a9759d70a 251 alp_retry_policy_t old_policy;
Jeej 6:287a9759d70a 252
Jeej 6:287a9759d70a 253 // Get old retry policy
Jeej 6:287a9759d70a 254 modem_read_file(WM_FID_ALP_CFG, &old_policy, MY_POLICY_IDX * sizeof(alp_retry_policy_t), sizeof(alp_retry_policy_t), g_main_id);
Jeej 0:fa3fd69f8148 255 modem_ready[g_main_id].wait();
Jeej 0:fa3fd69f8148 256
Jeej 6:287a9759d70a 257 if (!memcmp(&old_policy, &my_policy, sizeof(alp_retry_policy_t)))
Jeej 6:287a9759d70a 258 {
Jeej 6:287a9759d70a 259 // Set custom retry policy
Jeej 6:287a9759d70a 260 modem_write_file(WM_FID_ALP_CFG, &my_policy, MY_POLICY_IDX * sizeof(alp_retry_policy_t), sizeof(alp_retry_policy_t), g_main_id);
Jeej 6:287a9759d70a 261 modem_ready[g_main_id].wait();
Jeej 6:287a9759d70a 262 modem_flush_file(WM_FID_ALP_CFG, g_main_id);
Jeej 6:287a9759d70a 263 modem_ready[g_main_id].wait();
Jeej 6:287a9759d70a 264
Jeej 6:287a9759d70a 265 // XXX We need to reboot the modem for the changes to be applied
Jeej 6:287a9759d70a 266 my_reset();
Jeej 6:287a9759d70a 267 }
Jeej 0:fa3fd69f8148 268
Jeej 0:fa3fd69f8148 269 PRINT("Start D7A Stack\n");
Jeej 0:fa3fd69f8148 270 modem_activate_itf(ALP_ITF_TYPE_D7A, 24, 0, ALP_D7A_ISTAT_RESP | ALP_D7A_ISTAT_UNS, true, g_main_id);
Jeej 0:fa3fd69f8148 271 modem_ready[g_main_id].wait();
Jeej 0:fa3fd69f8148 272
Jeej 0:fa3fd69f8148 273 #ifdef DEBUG_BUTTON
Jeej 0:fa3fd69f8148 274 DebouncedInterrupt user_interrupt(DEBUG_BUTTON);
Jeej 0:fa3fd69f8148 275 user_interrupt.attach(button_push_isr, IRQ_FALL, 500, true);
Jeej 0:fa3fd69f8148 276
Jeej 0:fa3fd69f8148 277 Thread but_th(osPriorityNormal, 1024, NULL);
Jeej 0:fa3fd69f8148 278 osStatus status = but_th.start(button_user_thread);
Jeej 0:fa3fd69f8148 279 ASSERT(status == osOK, "Failed to start but thread (err: %d)\r\n", status);
Jeej 0:fa3fd69f8148 280 #endif
Jeej 0:fa3fd69f8148 281
Jeej 0:fa3fd69f8148 282 // Set main task to lowest priority
Jeej 0:fa3fd69f8148 283 osThreadSetPriority(osThreadGetId(), osPriorityIdle);
Jeej 0:fa3fd69f8148 284 while(true)
Jeej 0:fa3fd69f8148 285 {
Jeej 0:fa3fd69f8148 286 Thread::wait(500);
Jeej 0:fa3fd69f8148 287 }
Jeej 0:fa3fd69f8148 288 }