LoRaWAN demo.

Dependencies:   modem_ref_helper DebouncedInterrupt

Committer:
Jeej
Date:
Wed Jan 27 14:45:50 2021 +0000
Revision:
20:49a8ecd1dda3
Parent:
16:59d93cb1efee
Child:
21:f0aecd41db08
Sanity commit. Do not use.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 0:06ba20deb797 1 // @autor: jeremie@wizzilab.com
Jeej 0:06ba20deb797 2 // @date: 2017-09-21
Jeej 0:06ba20deb797 3
Jeej 0:06ba20deb797 4 #include "DebouncedInterrupt.h"
Jeej 20:49a8ecd1dda3 5 #include "modem_d7a.h"
Jeej 20:49a8ecd1dda3 6 #include "modem_lwan.h"
Jeej 20:49a8ecd1dda3 7 #include "d7a_callbacks.h"
Jeej 20:49a8ecd1dda3 8 #include "lwan_callbacks.h"
Jeej 0:06ba20deb797 9 #include "files.h"
Jeej 0:06ba20deb797 10 #include "sensor.h"
Jeej 0:06ba20deb797 11
Jeej 0:06ba20deb797 12 // Minimum time between alarms
Jeej 0:06ba20deb797 13 #define ALARM_COOLDOWN_TIME 10000 // ms
Jeej 2:9112445299fa 14 #define MIN_REPORT_PERIOD (10) // Seconds
Jeej 0:06ba20deb797 15
Jeej 0:06ba20deb797 16 enum {
Jeej 0:06ba20deb797 17 MODEM_RESP_NO,
Jeej 0:06ba20deb797 18 MODEM_RESP_TERMINAL,
Jeej 0:06ba20deb797 19 MODEM_RESP_DONE,
Jeej 0:06ba20deb797 20 };
Jeej 0:06ba20deb797 21
Jeej 0:06ba20deb797 22 Semaphore modem_ready[MAX_USER_NB];
Jeej 15:86f6fa566d89 23 Semaphore modem_urc(0);
Jeej 0:06ba20deb797 24 Semaphore button_user(0);
Jeej 0:06ba20deb797 25 sensor_config_t g_light_config;
Jeej 20:49a8ecd1dda3 26 Queue<uint8_t, 8> g_file_modified;
Jeej 0:06ba20deb797 27 Queue<void, 8> modem_resp;
Jeej 20:49a8ecd1dda3 28 Queue<uint32_t, 8> g_urc;
Jeej 20:49a8ecd1dda3 29 uint32_t itf_busy;
Jeej 16:59d93cb1efee 30 Timer busy_tim;
Jeej 0:06ba20deb797 31
Jeej 1:bca89c43e171 32 bool alarm_ready = false;
Jeej 0:06ba20deb797 33
wizziguy 5:2d5d3124703a 34 #define USE_WL_TTN
wizziguy 5:2d5d3124703a 35 #ifdef USE_WL_TTN
wizziguy 5:2d5d3124703a 36 // This is WizziLab's The Things Network LoRaWAN configuration file
wizziguy 5:2d5d3124703a 37 // This device is already registered on WizziLab's APP
wizziguy 5:2d5d3124703a 38 //
wizziguy 5:2d5d3124703a 39 // You can create your own account to get custom app_id and app_key.
wizziguy 5:2d5d3124703a 40 // The device EUI is the modem's UID.
wizziguy 5:2d5d3124703a 41 // https://account.thethingsnetwork.org/register
wizziguy 5:2d5d3124703a 42 // https://console.thethingsnetwork.org/applications
wizziguy 5:2d5d3124703a 43
wizziguy 5:2d5d3124703a 44 #define MY_APP_ID {0x70, 0xB3, 0xD5, 0x7E, 0xF0, 0x00, 0x3A, 0xF1 }
wizziguy 5:2d5d3124703a 45 #define MY_APP_KEY {0x73, 0x90, 0x54, 0x78, 0xB5, 0x0B, 0xA8, 0x9A, 0x78, 0x23, 0xB7, 0x12, 0xD5, 0x5C, 0x70, 0x99 }
wizziguy 5:2d5d3124703a 46 #else
wizziguy 5:2d5d3124703a 47 // This is your APP_ID and APP_KEY, as defined on your own TTN account
wizziguy 5:2d5d3124703a 48 // https://account.thethingsnetwork.org/register
wizziguy 5:2d5d3124703a 49 // https://console.thethingsnetwork.org/applications
wizziguy 5:2d5d3124703a 50
wizziguy 5:2d5d3124703a 51 #define MY_APP_ID { 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x00, 0xAC, 0xB2 }
wizziguy 5:2d5d3124703a 52 #define MY_APP_KEY { 0xDF, 0xF7, 0x26, 0x21, 0x22, 0xAD, 0x9A, 0xD6, 0x16, 0x84, 0xD1, 0x95, 0xBA, 0x8C, 0xD1, 0x1E }
wizziguy 5:2d5d3124703a 53
wizziguy 5:2d5d3124703a 54 #endif
wizziguy 5:2d5d3124703a 55
Jeej 20:49a8ecd1dda3 56 lwan_cfg_t lwan_cfg = {
Jeej 0:06ba20deb797 57 // LoRaWAN device class
Jeej 20:49a8ecd1dda3 58 .dev_class = LWAN_CLASS_A,
Jeej 0:06ba20deb797 59 // State of adaptative Datarate
Jeej 20:49a8ecd1dda3 60 .adr_enable = 1,
Jeej 0:06ba20deb797 61 // Uplink datarate, if adr_enable is off
Jeej 20:49a8ecd1dda3 62 .tx_datarate = 0,
Jeej 4:f83753357cdf 63 // ISM Band
Jeej 20:49a8ecd1dda3 64 .ism_band = ISM_BAND_868,
Jeej 20:49a8ecd1dda3 65 // maximum join attempts
Jeej 20:49a8ecd1dda3 66 .join_trials = 2,
Jeej 20:49a8ecd1dda3 67 // Rejoin period (hours)
Jeej 20:49a8ecd1dda3 68 .rejoin_period = 24
Jeej 20:49a8ecd1dda3 69 };
Jeej 20:49a8ecd1dda3 70
Jeej 20:49a8ecd1dda3 71 lwan_nls_t lwan_nls = {
Jeej 20:49a8ecd1dda3 72 // Application identifier
Jeej 20:49a8ecd1dda3 73 .app_id = MY_APP_ID,
Jeej 20:49a8ecd1dda3 74 // Application key
Jeej 20:49a8ecd1dda3 75 .app_key = MY_APP_KEY,
Jeej 0:06ba20deb797 76 };
Jeej 0:06ba20deb797 77
Jeej 20:49a8ecd1dda3 78 alp_d7a_itf_t report_itf = {
Jeej 20:49a8ecd1dda3 79 .type = ALP_ITF_TYPE_D7A,
Jeej 20:49a8ecd1dda3 80 .cfg.to = D7A_CTF(0),
Jeej 20:49a8ecd1dda3 81 .cfg.te = D7A_CTF(0),
Jeej 20:49a8ecd1dda3 82 .cfg.qos.bf.resp = D7A_RESP_PREFERRED,
Jeej 20:49a8ecd1dda3 83 .cfg.qos.bf.retry = ALP_RPOL_ONESHOT,
Jeej 20:49a8ecd1dda3 84 .cfg.addressee.ctrl.bf.nls = D7A_NLS_AES_CCM_64,
Jeej 20:49a8ecd1dda3 85 .cfg.addressee.ctrl.bf.idf = D7A_ID_NBID,
Jeej 20:49a8ecd1dda3 86 .cfg.addressee.xcl.bf = {.m = 0x1, .s = 2},// XXX D7A_XCL_GW,
Jeej 20:49a8ecd1dda3 87 .cfg.addressee.id = { D7A_CTF_ENCODE(2) }
Jeej 20:49a8ecd1dda3 88 };
Jeej 20:49a8ecd1dda3 89
Jeej 20:49a8ecd1dda3 90 modem_ref_callbacks_t callbacks = {
Jeej 20:49a8ecd1dda3 91 .read = my_read,
Jeej 20:49a8ecd1dda3 92 .write = my_write,
Jeej 20:49a8ecd1dda3 93 .read_fprop = my_read_fprop,
Jeej 20:49a8ecd1dda3 94 .flush = my_flush,
Jeej 20:49a8ecd1dda3 95 .remove = my_delete,
Jeej 20:49a8ecd1dda3 96 .udata = my_udata,
Jeej 20:49a8ecd1dda3 97 .lqual = my_lqual,
Jeej 20:49a8ecd1dda3 98 .ldown = my_ldown,
Jeej 20:49a8ecd1dda3 99 .reset = my_reset,
Jeej 20:49a8ecd1dda3 100 .boot = my_boot,
Jeej 20:49a8ecd1dda3 101 .busy = my_busy,
Jeej 20:49a8ecd1dda3 102 .itf_busy = NULL,
Jeej 20:49a8ecd1dda3 103 };
Jeej 20:49a8ecd1dda3 104
Jeej 20:49a8ecd1dda3 105 modem_lwan_callbacks_t lwan_callbacks = {
Jeej 20:49a8ecd1dda3 106 .packet_sent = lwan_packet_sent,
Jeej 20:49a8ecd1dda3 107 .itf_busy = lwan_busy,
Jeej 20:49a8ecd1dda3 108 .join_failed = lwan_join_failed,
Jeej 20:49a8ecd1dda3 109 };
Jeej 20:49a8ecd1dda3 110
Jeej 20:49a8ecd1dda3 111
Jeej 0:06ba20deb797 112 // Interrupt Service Routine on button press.
Jeej 0:06ba20deb797 113 void button_push_isr( void )
Jeej 0:06ba20deb797 114 {
Jeej 1:bca89c43e171 115 if (alarm_ready)
Jeej 0:06ba20deb797 116 {
Jeej 0:06ba20deb797 117 button_user.release();
Jeej 0:06ba20deb797 118 }
Jeej 0:06ba20deb797 119 else
Jeej 0:06ba20deb797 120 {
Jeej 0:06ba20deb797 121 PRINT("YOU CAN'T SEND ALARM AGAIN SO SOON.\n");
Jeej 0:06ba20deb797 122 }
Jeej 0:06ba20deb797 123 }
Jeej 0:06ba20deb797 124
Jeej 0:06ba20deb797 125 // Callback for id User
Jeej 0:06ba20deb797 126 void my_main_callback(uint8_t terminal, int8_t err, uint8_t id)
Jeej 0:06ba20deb797 127 {
Jeej 0:06ba20deb797 128 (void)id;
Jeej 0:06ba20deb797 129
Jeej 12:18ab0181d584 130 if (ALP_ERR_NONE != err)
Jeej 12:18ab0181d584 131 {
Jeej 12:18ab0181d584 132 modem_print_error(ALP_ITF_TYPE_D7A, err);
Jeej 12:18ab0181d584 133 }
Jeej 7:026f8c8bcdab 134
Jeej 0:06ba20deb797 135 if (terminal)
Jeej 12:18ab0181d584 136 {
Jeej 0:06ba20deb797 137 modem_ready[id].release();
Jeej 0:06ba20deb797 138 }
Jeej 0:06ba20deb797 139 }
Jeej 0:06ba20deb797 140
Jeej 2:9112445299fa 141 static bool report_ok(uint32_t last_report_time)
Jeej 2:9112445299fa 142 {
Jeej 2:9112445299fa 143 // Do not send a report if it's been less than MIN_REPORT_PERIOD since the last report
Jeej 2:9112445299fa 144 if ((last_report_time/1000) < MIN_REPORT_PERIOD)
Jeej 2:9112445299fa 145 {
Jeej 2:9112445299fa 146 PRINT("Report Skipped, next in %ds min\n", MIN_REPORT_PERIOD - (last_report_time/1000));
Jeej 2:9112445299fa 147 return false;
Jeej 2:9112445299fa 148 }
Jeej 2:9112445299fa 149
Jeej 2:9112445299fa 150 return true;
Jeej 2:9112445299fa 151 }
Jeej 2:9112445299fa 152
Jeej 0:06ba20deb797 153 // Check parameters to see if data should be send
Jeej 20:49a8ecd1dda3 154 static bool report_needed(sensor_config_t* config, int32_t value, int32_t last_value, uint32_t last_report_time)
Jeej 0:06ba20deb797 155 {
Jeej 2:9112445299fa 156 switch (config->report_type)
Jeej 0:06ba20deb797 157 {
Jeej 0:06ba20deb797 158 case REPORT_ALWAYS:
Jeej 0:06ba20deb797 159 // Send a report at each measure
Jeej 20:49a8ecd1dda3 160 PRINT("Report always\r\n");
Jeej 2:9112445299fa 161 return report_ok(last_report_time);
Jeej 0:06ba20deb797 162 case REPORT_ON_DIFFERENCE:
Jeej 0:06ba20deb797 163 // Send a report when the difference between the last reported measure and the current mesure is greater than max_diff
Jeej 2:9112445299fa 164 if (abs(last_value - value) >= config->max_diff && config->max_diff)
Jeej 0:06ba20deb797 165 {
Jeej 20:49a8ecd1dda3 166 PRINT("Report on difference (last:%d new:%d max_diff:%d)\r\n", last_value, value, config->max_diff);
Jeej 2:9112445299fa 167 return report_ok(last_report_time);
Jeej 0:06ba20deb797 168 }
Jeej 0:06ba20deb797 169 break;
Jeej 0:06ba20deb797 170 case REPORT_ON_THRESHOLD:
Jeej 0:06ba20deb797 171 // Send a report when crossing a threshold
Jeej 2:9112445299fa 172 if ( (value >= config->threshold_high && last_value < config->threshold_high)
Jeej 2:9112445299fa 173 || (value <= config->threshold_low && last_value > config->threshold_low)
Jeej 2:9112445299fa 174 || (value < config->threshold_high && last_value >= config->threshold_high)
Jeej 2:9112445299fa 175 || (value > config->threshold_low && last_value <= config->threshold_low))
Jeej 0:06ba20deb797 176 {
Jeej 20:49a8ecd1dda3 177 PRINT("Reporton threshold (last:%d new:%d th:%d tl:%d)\r\n", last_value, value, config->threshold_high, config->threshold_low);
Jeej 2:9112445299fa 178 return report_ok(last_report_time);
Jeej 0:06ba20deb797 179 }
Jeej 0:06ba20deb797 180 break;
Jeej 0:06ba20deb797 181 default:
Jeej 0:06ba20deb797 182 break;
Jeej 0:06ba20deb797 183 }
Jeej 0:06ba20deb797 184
Jeej 0:06ba20deb797 185 // Send a report if it's been more than max_period since the last report
Jeej 2:9112445299fa 186 if (((last_report_time/1000) >= config->max_period) && config->max_period)
Jeej 0:06ba20deb797 187 {
Jeej 20:49a8ecd1dda3 188 PRINT("Report on period (max_period:%d time:%d)\r\n", config->max_period, last_report_time);
Jeej 2:9112445299fa 189 return report_ok(last_report_time);
Jeej 0:06ba20deb797 190 }
Jeej 0:06ba20deb797 191
Jeej 0:06ba20deb797 192 return false;
Jeej 0:06ba20deb797 193 }
Jeej 0:06ba20deb797 194
Jeej 0:06ba20deb797 195 void thread_file_modified()
Jeej 0:06ba20deb797 196 {
Jeej 0:06ba20deb797 197 uint8_t fid;
Jeej 0:06ba20deb797 198 osEvent evt;
Jeej 0:06ba20deb797 199
Jeej 0:06ba20deb797 200 while (true)
Jeej 0:06ba20deb797 201 {
Jeej 0:06ba20deb797 202 evt = g_file_modified.get();
Jeej 0:06ba20deb797 203 fid = (evt.status == osEventMessage)? (uint8_t)(uint32_t)evt.value.p : NULL;
Jeej 0:06ba20deb797 204
Jeej 0:06ba20deb797 205 switch (fid)
Jeej 0:06ba20deb797 206 {
Jeej 0:06ba20deb797 207 case FID_SENSOR_CONFIG:
Jeej 0:06ba20deb797 208 // Update sensor configuration
Jeej 20:49a8ecd1dda3 209 ram_fs_read(FID_SENSOR_CONFIG, (uint8_t*)&g_light_config, 0, SIZE_SENSOR_CONFIG);
Jeej 0:06ba20deb797 210 PRINT("Sensor configuration updated\r\n");
Jeej 0:06ba20deb797 211 break;
Jeej 0:06ba20deb797 212 default:
Jeej 0:06ba20deb797 213 break;
Jeej 0:06ba20deb797 214 }
Jeej 0:06ba20deb797 215 }
Jeej 0:06ba20deb797 216 }
Jeej 0:06ba20deb797 217
Jeej 20:49a8ecd1dda3 218 void d7a_thread()
Jeej 20:49a8ecd1dda3 219 {
Jeej 20:49a8ecd1dda3 220 light_value_t light_level;
Jeej 20:49a8ecd1dda3 221 light_value_t light_level_old = 0;
Jeej 20:49a8ecd1dda3 222 alp_pub_payload_t* alp = NULL;
Jeej 20:49a8ecd1dda3 223 revision_t rev;
Jeej 20:49a8ecd1dda3 224
Jeej 20:49a8ecd1dda3 225 // To force a first report
Jeej 20:49a8ecd1dda3 226 uint32_t last_report_time = 0xFFFFFFFF;
Jeej 20:49a8ecd1dda3 227
Jeej 20:49a8ecd1dda3 228 // Add files to local file system
Jeej 20:49a8ecd1dda3 229 ram_fs_new(FID_SENSOR_CONFIG, (uint8_t*)&h_sensor_config, (uint8_t*)&f_sensor_config);
Jeej 20:49a8ecd1dda3 230 ram_fs_new(FID_ALARM, (uint8_t*)&h_alarm, (uint8_t*)&f_alarm);
Jeej 20:49a8ecd1dda3 231
Jeej 20:49a8ecd1dda3 232 DPRINT("D7A: Register Files\n");
Jeej 20:49a8ecd1dda3 233 // Allow remote access.
Jeej 20:49a8ecd1dda3 234 modem_declare_file(FID_SENSOR_CONFIG, (alp_file_header_t*)&h_sensor_config);
Jeej 20:49a8ecd1dda3 235 modem_declare_file(FID_ALARM, (alp_file_header_t*)&h_alarm);
Jeej 20:49a8ecd1dda3 236
Jeej 20:49a8ecd1dda3 237 PRINT("D7A: Notify Revision\n");
Jeej 20:49a8ecd1dda3 238
Jeej 20:49a8ecd1dda3 239 // Host revision file is in the modem. Update it.
Jeej 20:49a8ecd1dda3 240 modem_write_file(FID_HOST_REV, &f_rev, 0, sizeof(revision_t));
Jeej 20:49a8ecd1dda3 241
Jeej 20:49a8ecd1dda3 242 // Retrieve modem revision
Jeej 20:49a8ecd1dda3 243 modem_read_file(FID_WM_REV, &rev, 0, sizeof(revision_t));
Jeej 20:49a8ecd1dda3 244
Jeej 20:49a8ecd1dda3 245 // Send both to the server
Jeej 20:49a8ecd1dda3 246 // Build payload
Jeej 20:49a8ecd1dda3 247 alp = NULL;
Jeej 20:49a8ecd1dda3 248 alp = alp_payload_rsp_f_data(alp, FID_WM_REV, &rev, 0, sizeof(revision_t));
Jeej 20:49a8ecd1dda3 249 alp = alp_payload_rsp_f_data(alp, FID_HOST_REV, &f_rev, 0, sizeof(revision_t));
Jeej 20:49a8ecd1dda3 250 // Send
Jeej 20:49a8ecd1dda3 251 modem_remote_raw_alp(&report_itf, NULL, alp);
Jeej 20:49a8ecd1dda3 252
Jeej 20:49a8ecd1dda3 253 // Get the sensor configuration
Jeej 20:49a8ecd1dda3 254 ram_fs_read(FID_SENSOR_CONFIG, (uint8_t*)&g_light_config, 0, SIZE_SENSOR_CONFIG);
Jeej 20:49a8ecd1dda3 255
Jeej 20:49a8ecd1dda3 256 while (true)
Jeej 20:49a8ecd1dda3 257 {
Jeej 20:49a8ecd1dda3 258 light_level = sensor_get_light();
Jeej 20:49a8ecd1dda3 259
Jeej 20:49a8ecd1dda3 260 //PRINT("Light %d\r\n", light_level);
Jeej 20:49a8ecd1dda3 261
Jeej 20:49a8ecd1dda3 262 if (report_needed(&g_light_config, light_level, light_level_old, last_report_time))
Jeej 20:49a8ecd1dda3 263 {
Jeej 20:49a8ecd1dda3 264 PRINT("D7A: Light report %d\r\n", light_level);
Jeej 20:49a8ecd1dda3 265
Jeej 20:49a8ecd1dda3 266 // Send notification
Jeej 20:49a8ecd1dda3 267 modem_write_file(FID_SENSOR_LIGHT, &light_level, 0, SIZE_SENSOR_LIGHT);
Jeej 20:49a8ecd1dda3 268
Jeej 20:49a8ecd1dda3 269 // Update
Jeej 20:49a8ecd1dda3 270 light_level_old = light_level;
Jeej 20:49a8ecd1dda3 271 last_report_time = 0;
Jeej 20:49a8ecd1dda3 272 }
Jeej 20:49a8ecd1dda3 273
Jeej 20:49a8ecd1dda3 274 // Update last report time
Jeej 20:49a8ecd1dda3 275 last_report_time += g_light_config.read_period;
Jeej 20:49a8ecd1dda3 276
Jeej 20:49a8ecd1dda3 277 ThisThread::sleep_for(g_light_config.read_period);
Jeej 20:49a8ecd1dda3 278 }
Jeej 20:49a8ecd1dda3 279 }
Jeej 20:49a8ecd1dda3 280
Jeej 20:49a8ecd1dda3 281 void lwan_thread()
Jeej 0:06ba20deb797 282 {
Jeej 0:06ba20deb797 283 alarm_t alarm;
Jeej 20:49a8ecd1dda3 284 alp_pub_payload_t* alp = NULL;
Jeej 0:06ba20deb797 285
Jeej 20:49a8ecd1dda3 286 DebouncedInterrupt user_interrupt(DEBUG_BUTTON);
Jeej 20:49a8ecd1dda3 287 user_interrupt.attach(button_push_isr, IRQ_FALL, 500, true);
Jeej 0:06ba20deb797 288
Jeej 0:06ba20deb797 289 // Load alarm value
Jeej 20:49a8ecd1dda3 290 ram_fs_read(FID_ALARM, (uint8_t*)&alarm, 0, SIZE_ALARM);
Jeej 15:86f6fa566d89 291
Jeej 20:49a8ecd1dda3 292 PRINT("LoRaWAN: Update parameters\n");
Jeej 20:49a8ecd1dda3 293 modem_lwan_set_cfg(&lwan_cfg);
Jeej 20:49a8ecd1dda3 294 modem_lwan_set_nls(&lwan_nls);
Jeej 20:49a8ecd1dda3 295
Jeej 20:49a8ecd1dda3 296 PRINT("LoRaWAN: Start (first join)\n");
Jeej 20:49a8ecd1dda3 297 modem_lwan_open(&lwan_callbacks);
Jeej 0:06ba20deb797 298
Jeej 0:06ba20deb797 299 while (true)
Jeej 0:06ba20deb797 300 {
Jeej 0:06ba20deb797 301 // Wait for button press
Jeej 0:06ba20deb797 302 PRINT("PRESS BUTTON TO SEND LORAWAN ALARM...\r\n");
Jeej 1:bca89c43e171 303 alarm_ready = true;
Jeej 16:59d93cb1efee 304 button_user.acquire();
Jeej 1:bca89c43e171 305 alarm_ready = false;
Jeej 16:59d93cb1efee 306
Jeej 16:59d93cb1efee 307 itf_busy -= (int32_t)busy_tim.read();
Jeej 16:59d93cb1efee 308
Jeej 16:59d93cb1efee 309 if (itf_busy > 0)
Jeej 15:86f6fa566d89 310 {
Jeej 20:49a8ecd1dda3 311 PRINT("LoRaWAN: Still busy for %ds.\r\n", itf_busy);
Jeej 16:59d93cb1efee 312 busy_tim.reset();
Jeej 15:86f6fa566d89 313 }
Jeej 15:86f6fa566d89 314 else
Jeej 15:86f6fa566d89 315 {
Jeej 16:59d93cb1efee 316 busy_tim.stop();
Jeej 16:59d93cb1efee 317
Jeej 15:86f6fa566d89 318 // load/save value to keep choerency in case of remote access...
Jeej 20:49a8ecd1dda3 319 ram_fs_read(FID_ALARM, (uint8_t*)&alarm, 0, SIZE_ALARM);
Jeej 0:06ba20deb797 320
Jeej 15:86f6fa566d89 321 // Toggle alarm state
Jeej 15:86f6fa566d89 322 alarm = !alarm;
Jeej 15:86f6fa566d89 323
Jeej 20:49a8ecd1dda3 324 ram_fs_write(FID_ALARM, &alarm, 0, SIZE_ALARM);
Jeej 15:86f6fa566d89 325
Jeej 15:86f6fa566d89 326 PRINT("BUTTON ALARM %d\r\n", alarm);
Jeej 20:49a8ecd1dda3 327
Jeej 20:49a8ecd1dda3 328 // Build payload
Jeej 20:49a8ecd1dda3 329 alp = NULL;
Jeej 20:49a8ecd1dda3 330 alp = alp_payload_rsp_f_data(alp, FID_ALARM, &alarm, 0, sizeof(alarm_t));
Jeej 20:49a8ecd1dda3 331
Jeej 20:49a8ecd1dda3 332 // Send
Jeej 20:49a8ecd1dda3 333 modem_lwan_send(alp);
Jeej 15:86f6fa566d89 334 }
Jeej 15:86f6fa566d89 335 }
Jeej 15:86f6fa566d89 336 }
Jeej 15:86f6fa566d89 337
Jeej 0:06ba20deb797 338
Jeej 0:06ba20deb797 339 /*** Main function ------------------------------------------------------------- ***/
Jeej 0:06ba20deb797 340 int main()
Jeej 0:06ba20deb797 341 {
Jeej 0:06ba20deb797 342 // Start & initialize
Jeej 0:06ba20deb797 343 #ifdef DEBUG_LED
Jeej 0:06ba20deb797 344 DBG_OPEN(DEBUG_LED);
Jeej 0:06ba20deb797 345 #else
Jeej 0:06ba20deb797 346 DBG_OPEN(NC);
Jeej 0:06ba20deb797 347 #endif
Jeej 0:06ba20deb797 348 PRINT("\n"
Jeej 0:06ba20deb797 349 "-----------------------------------------\n"
Jeej 0:06ba20deb797 350 "-------------- Demo LoRaWAN -------------\n"
Jeej 0:06ba20deb797 351 "-----------------------------------------\n");
Jeej 20:49a8ecd1dda3 352
Jeej 20:49a8ecd1dda3 353 modem_open(&callbacks);
Jeej 0:06ba20deb797 354
Jeej 0:06ba20deb797 355 // Start file modified thread
Jeej 0:06ba20deb797 356 Thread th_file_modified(osPriorityNormal, 1024, NULL);
Jeej 0:06ba20deb797 357 osStatus status = th_file_modified.start(thread_file_modified);
Jeej 0:06ba20deb797 358 ASSERT(status == osOK, "Failed to start thread_file_modified (err: %d)\r\n", status);
Jeej 0:06ba20deb797 359
Jeej 0:06ba20deb797 360 // Start light measure thread
Jeej 0:06ba20deb797 361 Thread th_sensor_light(osPriorityNormal, 1024, NULL);
Jeej 20:49a8ecd1dda3 362 status = th_sensor_light.start(d7a_thread);
Jeej 20:49a8ecd1dda3 363 ASSERT(status == osOK, "Failed to start d7a_thread (err: %d)\r\n", status);
Jeej 0:06ba20deb797 364
Jeej 0:06ba20deb797 365 Thread but_th(osPriorityNormal, 1024, NULL);
Jeej 20:49a8ecd1dda3 366 status = but_th.start(lwan_thread);
Jeej 0:06ba20deb797 367 ASSERT(status == osOK, "Failed to start but thread (err: %d)\r\n", status);
Jeej 0:06ba20deb797 368
Jeej 0:06ba20deb797 369 #ifdef DEBUG_LED
Jeej 0:06ba20deb797 370 DigitalOut my_led(DEBUG_LED);
Jeej 0:06ba20deb797 371 #endif
Jeej 0:06ba20deb797 372
Jeej 0:06ba20deb797 373 // Set main task to lowest priority
Jeej 16:59d93cb1efee 374 osThreadSetPriority(osThreadGetId(), osPriorityLow);
Jeej 0:06ba20deb797 375 while(true)
Jeej 0:06ba20deb797 376 {
Jeej 16:59d93cb1efee 377 ThisThread::sleep_for(500);
Jeej 0:06ba20deb797 378 #ifdef DEBUG_LED
Jeej 0:06ba20deb797 379 my_led = !my_led;
Jeej 0:06ba20deb797 380 #endif
Jeej 0:06ba20deb797 381 }
Jeej 0:06ba20deb797 382 }