Ping pong app demo.

Dependencies:   modem_ref_helper DebouncedInterrupt

Committer:
Jeej
Date:
Thu May 18 13:09:03 2017 +0000
Revision:
2:785b422c7d22
Parent:
1:4629ccf8315d
Child:
3:0979d8cba5ec
Factorized libraries.

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