Ping pong app demo.

Dependencies:   modem_ref_helper DebouncedInterrupt

Committer:
Jeej
Date:
Thu Sep 21 15:14:08 2017 +0000
Revision:
3:0979d8cba5ec
Parent:
2:785b422c7d22
Child:
6:287a9759d70a
Updated for v4.10.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 3:0979d8cba5ec 39 // the transmission we be stopped by the duty cycle limit after several PINGs.
Jeej 3:0979d8cba5ec 40
Jeej 0:fa3fd69f8148 41 d7a_xcl_t ping_pong_xcl = { .bf.s = 13, .bf.m = 1 };
Jeej 0:fa3fd69f8148 42
Jeej 0:fa3fd69f8148 43 alp_retry_policy_t my_policy = {
Jeej 0:fa3fd69f8148 44 .meta.procedure = 0,
Jeej 0:fa3fd69f8148 45 .meta.respond = true,
Jeej 0:fa3fd69f8148 46 .meta.persistant = false,
Jeej 0:fa3fd69f8148 47 .meta.bulk = false,
Jeej 0:fa3fd69f8148 48 .depth = 1,
Jeej 0:fa3fd69f8148 49 .retries = 0,
Jeej 0:fa3fd69f8148 50 .slot_time = 0
Jeej 0:fa3fd69f8148 51 };
Jeej 0:fa3fd69f8148 52
Jeej 0:fa3fd69f8148 53 alp_d7a_itf_t my_itf = {
Jeej 0:fa3fd69f8148 54 .type = ALP_ITF_TYPE_D7A,
Jeej 0:fa3fd69f8148 55 .cfg.to = 0,
Jeej 0:fa3fd69f8148 56 .cfg.te = 0,
Jeej 0:fa3fd69f8148 57 .cfg.qos.bf.resp = D7A_RESP_NO,
Jeej 0:fa3fd69f8148 58 .cfg.qos.bf.retry = MY_POLICY_IDX,
Jeej 0:fa3fd69f8148 59 .cfg.qos.bf.record = 0,
Jeej 0:fa3fd69f8148 60 .cfg.qos.bf.stop_on_err = 0,
Jeej 0:fa3fd69f8148 61 .cfg.addressee.ctrl.bf.nls = D7A_NLS_AES_CCM_64,
Jeej 0:fa3fd69f8148 62 .cfg.addressee.ctrl.bf.idf = D7A_ID_NOID,
Jeej 0:fa3fd69f8148 63 .cfg.addressee.xcl = ping_pong_xcl
Jeej 0:fa3fd69f8148 64 };
Jeej 0:fa3fd69f8148 65
Jeej 0:fa3fd69f8148 66 void print_status(int status)
Jeej 0:fa3fd69f8148 67 {
Jeej 0:fa3fd69f8148 68 switch (status)
Jeej 0:fa3fd69f8148 69 {
Jeej 0:fa3fd69f8148 70 case ALP_ERR_NONE:
Jeej 3:0979d8cba5ec 71 //PRINT("Status: OK\n");
Jeej 0:fa3fd69f8148 72 break;
Jeej 0:fa3fd69f8148 73 case ALP_ERR_FILE_EXIST:
Jeej 0:fa3fd69f8148 74 PRINT("Status: Already registered\n");
Jeej 0:fa3fd69f8148 75 break;
Jeej 0:fa3fd69f8148 76 default:
Jeej 0:fa3fd69f8148 77 PRINT("Status: error %d\n", status);
Jeej 0:fa3fd69f8148 78 break;
Jeej 0:fa3fd69f8148 79 }
Jeej 0:fa3fd69f8148 80 }
Jeej 0:fa3fd69f8148 81
Jeej 0:fa3fd69f8148 82 void print_resp(int status)
Jeej 0:fa3fd69f8148 83 {
Jeej 0:fa3fd69f8148 84 switch (status)
Jeej 0:fa3fd69f8148 85 {
Jeej 0:fa3fd69f8148 86 case ALP_ERR_NONE:
Jeej 3:0979d8cba5ec 87 //PRINT("Resp: OK\n");
Jeej 0:fa3fd69f8148 88 break;
Jeej 0:fa3fd69f8148 89 case ALP_ERR_FILE_EXIST:
Jeej 0:fa3fd69f8148 90 PRINT("Resp: Already registered\n");
Jeej 0:fa3fd69f8148 91 break;
Jeej 0:fa3fd69f8148 92 default:
Jeej 0:fa3fd69f8148 93 PRINT("Resp: error %d\n", status);
Jeej 0:fa3fd69f8148 94 break;
Jeej 0:fa3fd69f8148 95 }
Jeej 0:fa3fd69f8148 96 }
Jeej 0:fa3fd69f8148 97
Jeej 0:fa3fd69f8148 98 // Callback for User
Jeej 0:fa3fd69f8148 99 void my_main_callback(uint8_t terminal, int8_t err, uint8_t id)
Jeej 0:fa3fd69f8148 100 {
Jeej 0:fa3fd69f8148 101 (void)id;
Jeej 0:fa3fd69f8148 102
Jeej 0:fa3fd69f8148 103 if (terminal)
Jeej 0:fa3fd69f8148 104 {
Jeej 0:fa3fd69f8148 105 print_status(err);
Jeej 0:fa3fd69f8148 106 modem_ready[id].release();
Jeej 0:fa3fd69f8148 107 }
Jeej 0:fa3fd69f8148 108 else
Jeej 0:fa3fd69f8148 109 {
Jeej 0:fa3fd69f8148 110 print_resp(err);
Jeej 0:fa3fd69f8148 111 }
Jeej 0:fa3fd69f8148 112 }
Jeej 0:fa3fd69f8148 113
Jeej 0:fa3fd69f8148 114 void my_void_callback(uint8_t terminal, int8_t err, uint8_t id)
Jeej 0:fa3fd69f8148 115 {
Jeej 0:fa3fd69f8148 116 (void)terminal;
Jeej 0:fa3fd69f8148 117 (void)id;
Jeej 0:fa3fd69f8148 118 print_status(err);
Jeej 0:fa3fd69f8148 119 }
Jeej 0:fa3fd69f8148 120
Jeej 0:fa3fd69f8148 121
Jeej 0:fa3fd69f8148 122 // Interrupt Service Routine on button press.
Jeej 0:fa3fd69f8148 123 void button_push_isr( void )
Jeej 0:fa3fd69f8148 124 {
Jeej 0:fa3fd69f8148 125 button_user.release();
Jeej 0:fa3fd69f8148 126 }
Jeej 0:fa3fd69f8148 127
Jeej 2:785b422c7d22 128 #ifdef DEBUG_LED
Jeej 0:fa3fd69f8148 129 DigitalOut my_led(DEBUG_LED);
Jeej 0:fa3fd69f8148 130 #endif
Jeej 0:fa3fd69f8148 131
Jeej 3:0979d8cba5ec 132 void my_udata(u8 fid, void *data, u32 offset, u32 length, u8 i_type, u8 i_length, u8* i_data)
Jeej 0:fa3fd69f8148 133 {
Jeej 0:fa3fd69f8148 134 (void)data;
Jeej 0:fa3fd69f8148 135 (void)i_length;
Jeej 0:fa3fd69f8148 136
Jeej 3:0979d8cba5ec 137 if (i_type == ALP_ITF_TYPE_D7A)
Jeej 0:fa3fd69f8148 138 {
Jeej 0:fa3fd69f8148 139 d7a_sp_res_t* istat = (d7a_sp_res_t*)i_data;
Jeej 3:0979d8cba5ec 140
Jeej 3:0979d8cba5ec 141 if(fid == FID_PING_PONG && offset == 0 && length == PING_COUNTER_SIZE)
Jeej 3:0979d8cba5ec 142 {
Jeej 3:0979d8cba5ec 143 uint32_t* count = (uint32_t*)data;
Jeej 3:0979d8cba5ec 144
Jeej 3:0979d8cba5ec 145 PRINT("Got PING %d", *count);
Jeej 3:0979d8cba5ec 146 PRINT_DATA(" from ", "%02X", istat->addressee.id, 8, "");
Jeej 3:0979d8cba5ec 147 PRINT(" (SNR:%d dB RXLEV:%d dBm LB:%d dB)\n", istat->snr, -istat->rxlev, istat->lb);
Jeej 3:0979d8cba5ec 148
Jeej 3:0979d8cba5ec 149 #ifdef DEBUG_LED
Jeej 3:0979d8cba5ec 150 my_led = 1;
Jeej 3:0979d8cba5ec 151 #endif
Jeej 0:fa3fd69f8148 152
Jeej 3:0979d8cba5ec 153 Thread::wait(PING_DELAY);
Jeej 3:0979d8cba5ec 154
Jeej 3:0979d8cba5ec 155 #ifdef DEBUG_LED
Jeej 3:0979d8cba5ec 156 my_led = 0;
Jeej 3:0979d8cba5ec 157 #endif
Jeej 3:0979d8cba5ec 158
Jeej 3:0979d8cba5ec 159 alp_d7a_itf_t resp_itf = {
Jeej 3:0979d8cba5ec 160 .type = ALP_ITF_TYPE_D7A,
Jeej 3:0979d8cba5ec 161 .cfg.to = 0,
Jeej 3:0979d8cba5ec 162 .cfg.te = 0,
Jeej 3:0979d8cba5ec 163 .cfg.qos.bf.resp = D7A_RESP_NO,
Jeej 3:0979d8cba5ec 164 .cfg.qos.bf.retry = MY_POLICY_IDX,
Jeej 3:0979d8cba5ec 165 .cfg.qos.bf.record = 0,
Jeej 3:0979d8cba5ec 166 .cfg.qos.bf.stop_on_err = 0,
Jeej 3:0979d8cba5ec 167 .cfg.addressee = istat->addressee,
Jeej 3:0979d8cba5ec 168 };
Jeej 3:0979d8cba5ec 169
Jeej 3:0979d8cba5ec 170 (*count)++;
Jeej 3:0979d8cba5ec 171
Jeej 3:0979d8cba5ec 172 // Send ping
Jeej 3:0979d8cba5ec 173 PRINT("Send PING %d", *count);
Jeej 3:0979d8cba5ec 174 PRINT_DATA(" to ", "%02X", resp_itf.cfg.addressee.id, 8, "\n");
Jeej 3:0979d8cba5ec 175
Jeej 3:0979d8cba5ec 176 modem_send_file_content((uint8_t*)&resp_itf, D7_ITF_SIZE(&resp_itf), istat, FID_PING_PONG, count, 0, PING_COUNTER_SIZE, g_void_id);
Jeej 3:0979d8cba5ec 177 }
Jeej 0:fa3fd69f8148 178 }
Jeej 0:fa3fd69f8148 179 }
Jeej 0:fa3fd69f8148 180
Jeej 0:fa3fd69f8148 181 void button_user_thread()
Jeej 0:fa3fd69f8148 182 {
Jeej 0:fa3fd69f8148 183 d7a_sp_res_t istat;
Jeej 0:fa3fd69f8148 184 uint32_t ping = 0;
Jeej 0:fa3fd69f8148 185
Jeej 0:fa3fd69f8148 186 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:fa3fd69f8148 187
Jeej 0:fa3fd69f8148 188 while (true)
Jeej 0:fa3fd69f8148 189 {
Jeej 0:fa3fd69f8148 190 // Wait for button press
Jeej 3:0979d8cba5ec 191 PRINT("PRESS BUTTON TO INITIATE PING...\n");
Jeej 0:fa3fd69f8148 192 button_user.wait();
Jeej 0:fa3fd69f8148 193
Jeej 0:fa3fd69f8148 194 // Initiate ping
Jeej 0:fa3fd69f8148 195 PRINT("Initiate PING\n");
Jeej 2:785b422c7d22 196 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 197 modem_ready[g_main_id].wait();
Jeej 0:fa3fd69f8148 198 }
Jeej 0:fa3fd69f8148 199 }
Jeej 0:fa3fd69f8148 200
Jeej 0:fa3fd69f8148 201 modem_callbacks_t callbacks = {
Jeej 0:fa3fd69f8148 202 .read = my_read,
Jeej 0:fa3fd69f8148 203 .write = my_write,
Jeej 0:fa3fd69f8148 204 .read_fprop = my_read_fprop,
Jeej 0:fa3fd69f8148 205 .flush = my_flush,
Jeej 0:fa3fd69f8148 206 .remove = my_delete,
Jeej 0:fa3fd69f8148 207 .udata = my_udata,
Jeej 0:fa3fd69f8148 208 .lqual = my_lqual,
Jeej 0:fa3fd69f8148 209 .ldown = my_ldown,
Jeej 0:fa3fd69f8148 210 .reset = my_reset,
Jeej 0:fa3fd69f8148 211 .boot = my_boot
Jeej 0:fa3fd69f8148 212 };
Jeej 0:fa3fd69f8148 213
Jeej 0:fa3fd69f8148 214 /*** Main function ------------------------------------------------------------- ***/
Jeej 0:fa3fd69f8148 215 int main()
Jeej 0:fa3fd69f8148 216 {
Jeej 0:fa3fd69f8148 217 // Start & initialize
Jeej 2:785b422c7d22 218 #ifdef DEBUG_LED
Jeej 0:fa3fd69f8148 219 DBG_OPEN(DEBUG_LED);
Jeej 2:785b422c7d22 220 #else
Jeej 2:785b422c7d22 221 DBG_OPEN(NC);
Jeej 2:785b422c7d22 222 #endif
Jeej 3:0979d8cba5ec 223 PRINT("\n"
Jeej 3:0979d8cba5ec 224 "-----------------------------------------\n"
Jeej 3:0979d8cba5ec 225 "------------ Demo Ping Pong -------------\n"
Jeej 3:0979d8cba5ec 226 "-----------------------------------------\n");
Jeej 3:0979d8cba5ec 227
Jeej 0:fa3fd69f8148 228 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:fa3fd69f8148 229
Jeej 2:785b422c7d22 230 modem_helper_open(&callbacks);
Jeej 0:fa3fd69f8148 231
Jeej 0:fa3fd69f8148 232 g_main_id = modem_get_id(my_main_callback);
Jeej 1:4629ccf8315d 233
Jeej 0:fa3fd69f8148 234 // Put modem to listen to this access class
Jeej 0:fa3fd69f8148 235 modem_write_file(D7A_FID_DLL_CFG, &ping_pong_xcl, 0, sizeof(d7a_xcl_t), g_main_id);
Jeej 0:fa3fd69f8148 236 modem_ready[g_main_id].wait();
Jeej 0:fa3fd69f8148 237
Jeej 0:fa3fd69f8148 238 // Set custom retry policy
Jeej 0:fa3fd69f8148 239 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 0:fa3fd69f8148 240 modem_ready[g_main_id].wait();
Jeej 0:fa3fd69f8148 241
Jeej 0:fa3fd69f8148 242 // Configure URC: LQUAL on report file notification every 10 reports
Jeej 0:fa3fd69f8148 243 PRINT("Setup URCs\n");
Jeej 0:fa3fd69f8148 244 modem_enable_urc(ALP_URC_TYPE_LQUAL, IFID_REPORT, 10, true, g_main_id);
Jeej 0:fa3fd69f8148 245 modem_ready[g_main_id].wait();
Jeej 0:fa3fd69f8148 246
Jeej 0:fa3fd69f8148 247 PRINT("Start D7A Stack\n");
Jeej 0:fa3fd69f8148 248 modem_activate_itf(ALP_ITF_TYPE_D7A, 24, 0, ALP_D7A_ISTAT_RESP | ALP_D7A_ISTAT_UNS, true, g_main_id);
Jeej 0:fa3fd69f8148 249 modem_ready[g_main_id].wait();
Jeej 0:fa3fd69f8148 250
Jeej 0:fa3fd69f8148 251 #ifdef DEBUG_BUTTON
Jeej 0:fa3fd69f8148 252 DebouncedInterrupt user_interrupt(DEBUG_BUTTON);
Jeej 0:fa3fd69f8148 253 user_interrupt.attach(button_push_isr, IRQ_FALL, 500, true);
Jeej 0:fa3fd69f8148 254
Jeej 0:fa3fd69f8148 255 Thread but_th(osPriorityNormal, 1024, NULL);
Jeej 0:fa3fd69f8148 256 osStatus status = but_th.start(button_user_thread);
Jeej 0:fa3fd69f8148 257 ASSERT(status == osOK, "Failed to start but thread (err: %d)\r\n", status);
Jeej 0:fa3fd69f8148 258 #endif
Jeej 0:fa3fd69f8148 259
Jeej 0:fa3fd69f8148 260 // Set main task to lowest priority
Jeej 0:fa3fd69f8148 261 osThreadSetPriority(osThreadGetId(), osPriorityIdle);
Jeej 0:fa3fd69f8148 262 while(true)
Jeej 0:fa3fd69f8148 263 {
Jeej 0:fa3fd69f8148 264 Thread::wait(500);
Jeej 0:fa3fd69f8148 265 }
Jeej 0:fa3fd69f8148 266 }