Demo fro training
Dependencies: X_NUCLEO_IKS01A1 d7a_1x mbed-rtos mbed wizzi-utils
main.cpp@0:429446fe396d, 2016-11-21 (annotated)
- Committer:
- mikl_andre
- Date:
- Mon Nov 21 07:24:34 2016 +0000
- Revision:
- 0:429446fe396d
Initial Revision
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mikl_andre | 0:429446fe396d | 1 | // This project is a demo of the DASH7 1.x stack |
mikl_andre | 0:429446fe396d | 2 | // @autor: jeremie@wizzilab.com |
mikl_andre | 0:429446fe396d | 3 | // @date: 2016-08-23 |
mikl_andre | 0:429446fe396d | 4 | // |
mikl_andre | 0:429446fe396d | 5 | // ----- SETUP ----- |
mikl_andre | 0:429446fe396d | 6 | // This programm has been tested with the following hardware: |
mikl_andre | 0:429446fe396d | 7 | // --> NUCLEO-L152RE + DASH7 enabled SHIELD_SP1ML_v1.0 |
mikl_andre | 0:429446fe396d | 8 | // For this demo to work, you need the previously described hardware. |
mikl_andre | 0:429446fe396d | 9 | // A DASH7 1.x gateway have to be available in your area in order to retreive the data. |
mikl_andre | 0:429446fe396d | 10 | // |
mikl_andre | 0:429446fe396d | 11 | // ----- FILE SYSTEM ----- |
mikl_andre | 0:429446fe396d | 12 | // DASH7 is a file system based protocol. You read and write in files that are present on your device or your modem. |
mikl_andre | 0:429446fe396d | 13 | // Some callbacks can be implemented by the user for allowing the stack to acceed the local file system. (See description of the callbacks for more details) |
mikl_andre | 0:429446fe396d | 14 | // The file system is user defined and can be changed to fit your needs. |
mikl_andre | 0:429446fe396d | 15 | // This demo uses a simple RAM file system. |
mikl_andre | 0:429446fe396d | 16 | // The files are defined in files.h |
mikl_andre | 0:429446fe396d | 17 | // The files values are initialized in files.cpp |
mikl_andre | 0:429446fe396d | 18 | // |
mikl_andre | 0:429446fe396d | 19 | // ----- SENSORS ----- |
mikl_andre | 0:429446fe396d | 20 | // The sensors can be simulated (random data). |
mikl_andre | 0:429446fe396d | 21 | // |
mikl_andre | 0:429446fe396d | 22 | // ----- DEMO ----- |
mikl_andre | 0:429446fe396d | 23 | // This demo starts 7 threads (one for each sensor value) that will periodically read the sensor value |
mikl_andre | 0:429446fe396d | 24 | // and depending on the sensor configuration file, will send the data to the DASH7 network (notification) |
mikl_andre | 0:429446fe396d | 25 | // You can also report the alarm status by pushing the board's button (blue) |
mikl_andre | 0:429446fe396d | 26 | // |
mikl_andre | 0:429446fe396d | 27 | // ----- DEBUG ----- |
mikl_andre | 0:429446fe396d | 28 | // Several debugging options are available in wizzi-utils/dbg/dbg.h |
mikl_andre | 0:429446fe396d | 29 | // An ASSERT is a fatal error. By default, this error will reboot the device. |
mikl_andre | 0:429446fe396d | 30 | |
mikl_andre | 0:429446fe396d | 31 | #include "mbed.h" |
mikl_andre | 0:429446fe396d | 32 | #include "rtos.h" |
mikl_andre | 0:429446fe396d | 33 | #include "rtos_idle.h" |
mikl_andre | 0:429446fe396d | 34 | #include "d7a.h" |
mikl_andre | 0:429446fe396d | 35 | #include "sensors.h" |
mikl_andre | 0:429446fe396d | 36 | #include "simul.h" |
mikl_andre | 0:429446fe396d | 37 | #include "dbg.h" |
mikl_andre | 0:429446fe396d | 38 | #include "DebouncedInterrupt.h" |
mikl_andre | 0:429446fe396d | 39 | #include "files.h" |
mikl_andre | 0:429446fe396d | 40 | |
mikl_andre | 0:429446fe396d | 41 | // Select the sensors |
mikl_andre | 0:429446fe396d | 42 | #if 0 |
mikl_andre | 0:429446fe396d | 43 | #define _MAG_EN_ 1 |
mikl_andre | 0:429446fe396d | 44 | #define _ACC_EN_ 1 |
mikl_andre | 0:429446fe396d | 45 | #define _GYR_EN_ 1 |
mikl_andre | 0:429446fe396d | 46 | #define _PRE_EN_ 1 |
mikl_andre | 0:429446fe396d | 47 | #define _HUM_EN_ 1 |
mikl_andre | 0:429446fe396d | 48 | #define _TEM1_EN_ 1 |
mikl_andre | 0:429446fe396d | 49 | #define _TEM2_EN_ 1 |
mikl_andre | 0:429446fe396d | 50 | #else |
mikl_andre | 0:429446fe396d | 51 | #define _MAG_EN_ 0 |
mikl_andre | 0:429446fe396d | 52 | #define _ACC_EN_ 0 |
mikl_andre | 0:429446fe396d | 53 | #define _GYR_EN_ 0 |
mikl_andre | 0:429446fe396d | 54 | #define _PRE_EN_ 0 |
mikl_andre | 0:429446fe396d | 55 | #define _HUM_EN_ 0 |
mikl_andre | 0:429446fe396d | 56 | #define _TEM1_EN_ 0 |
mikl_andre | 0:429446fe396d | 57 | #define _TEM2_EN_ 0 |
mikl_andre | 0:429446fe396d | 58 | #endif |
mikl_andre | 0:429446fe396d | 59 | |
mikl_andre | 0:429446fe396d | 60 | // Semaphore for notifiying button presses |
mikl_andre | 0:429446fe396d | 61 | Semaphore button_user(0); |
mikl_andre | 0:429446fe396d | 62 | |
mikl_andre | 0:429446fe396d | 63 | // Interrupt Service Routine on button press. |
mikl_andre | 0:429446fe396d | 64 | void button_push_isr( void ) |
mikl_andre | 0:429446fe396d | 65 | { |
mikl_andre | 0:429446fe396d | 66 | button_user.release(); |
mikl_andre | 0:429446fe396d | 67 | } |
mikl_andre | 0:429446fe396d | 68 | |
mikl_andre | 0:429446fe396d | 69 | // file modified queue |
mikl_andre | 0:429446fe396d | 70 | Queue<void, 8> fm_queue; |
mikl_andre | 0:429446fe396d | 71 | |
mikl_andre | 0:429446fe396d | 72 | |
mikl_andre | 0:429446fe396d | 73 | // ----------------------------------------------- |
mikl_andre | 0:429446fe396d | 74 | // callbacks |
mikl_andre | 0:429446fe396d | 75 | // ----------------------------------------------- |
mikl_andre | 0:429446fe396d | 76 | /** |
mikl_andre | 0:429446fe396d | 77 | Write data into a file. |
mikl_andre | 0:429446fe396d | 78 | |
mikl_andre | 0:429446fe396d | 79 | @param const uint8_t File ID |
mikl_andre | 0:429446fe396d | 80 | @param const uint16_t Offset from start of data |
mikl_andre | 0:429446fe396d | 81 | @param const uint16_t Size of data to be written |
mikl_andre | 0:429446fe396d | 82 | @param const uint8_t* const Pointer to the data to write |
mikl_andre | 0:429446fe396d | 83 | @return uint32_t Size of written data |
mikl_andre | 0:429446fe396d | 84 | */ |
mikl_andre | 0:429446fe396d | 85 | uint32_t write_file_callback(const uint8_t file_id, |
mikl_andre | 0:429446fe396d | 86 | const uint16_t offset, |
mikl_andre | 0:429446fe396d | 87 | const uint16_t size, |
mikl_andre | 0:429446fe396d | 88 | const uint8_t* const content) |
mikl_andre | 0:429446fe396d | 89 | { |
mikl_andre | 0:429446fe396d | 90 | uint32_t ret = 0; |
mikl_andre | 0:429446fe396d | 91 | |
mikl_andre | 0:429446fe396d | 92 | IPRINT("Write file %d offset:%d size:%d\r\n", file_id, offset, size); |
mikl_andre | 0:429446fe396d | 93 | |
mikl_andre | 0:429446fe396d | 94 | ret = fs_write_file(file_id, offset, size, content); |
mikl_andre | 0:429446fe396d | 95 | |
mikl_andre | 0:429446fe396d | 96 | WARNING(ret, "File %d not found\r\n", file_id); |
mikl_andre | 0:429446fe396d | 97 | |
mikl_andre | 0:429446fe396d | 98 | // Indicate that the file has been modified |
mikl_andre | 0:429446fe396d | 99 | fm_queue.put((void*)file_id); |
mikl_andre | 0:429446fe396d | 100 | |
mikl_andre | 0:429446fe396d | 101 | return ret; |
mikl_andre | 0:429446fe396d | 102 | } |
mikl_andre | 0:429446fe396d | 103 | |
mikl_andre | 0:429446fe396d | 104 | /** |
mikl_andre | 0:429446fe396d | 105 | Read data from a file. |
mikl_andre | 0:429446fe396d | 106 | |
mikl_andre | 0:429446fe396d | 107 | @param const uint8_t File ID |
mikl_andre | 0:429446fe396d | 108 | @param const uint16_t Offset from start of data |
mikl_andre | 0:429446fe396d | 109 | @param const uint16_t Size of data to be read |
mikl_andre | 0:429446fe396d | 110 | @param const uint8_t* const Pointer to the reading buffer |
mikl_andre | 0:429446fe396d | 111 | @return uint32_t Size of read data |
mikl_andre | 0:429446fe396d | 112 | */ |
mikl_andre | 0:429446fe396d | 113 | uint32_t read_file_callback(const uint8_t file_id, |
mikl_andre | 0:429446fe396d | 114 | const uint16_t offset, |
mikl_andre | 0:429446fe396d | 115 | const uint16_t size, |
mikl_andre | 0:429446fe396d | 116 | uint8_t* buf) |
mikl_andre | 0:429446fe396d | 117 | { |
mikl_andre | 0:429446fe396d | 118 | uint32_t ret = 0; |
mikl_andre | 0:429446fe396d | 119 | |
mikl_andre | 0:429446fe396d | 120 | IPRINT("Read file %d offset:%d size:%d\r\n", file_id, offset, size); |
mikl_andre | 0:429446fe396d | 121 | |
mikl_andre | 0:429446fe396d | 122 | ret = fs_read_file(file_id, offset, size, buf); |
mikl_andre | 0:429446fe396d | 123 | |
mikl_andre | 0:429446fe396d | 124 | WARNING(ret, "File %d not found\r\n", file_id); |
mikl_andre | 0:429446fe396d | 125 | |
mikl_andre | 0:429446fe396d | 126 | return ret; |
mikl_andre | 0:429446fe396d | 127 | } |
mikl_andre | 0:429446fe396d | 128 | |
mikl_andre | 0:429446fe396d | 129 | /** |
mikl_andre | 0:429446fe396d | 130 | Called when a notification is finished |
mikl_andre | 0:429446fe396d | 131 | |
mikl_andre | 0:429446fe396d | 132 | @param const uint8_t File ID |
mikl_andre | 0:429446fe396d | 133 | @param const uint8_t Error code |
mikl_andre | 0:429446fe396d | 134 | @return void |
mikl_andre | 0:429446fe396d | 135 | */ |
mikl_andre | 0:429446fe396d | 136 | void notif_done_callback(const uint8_t file_id, const uint8_t error) |
mikl_andre | 0:429446fe396d | 137 | { |
mikl_andre | 0:429446fe396d | 138 | PRINT("Notif FID %d done. err %d\r\n", file_id, error); |
mikl_andre | 0:429446fe396d | 139 | } |
mikl_andre | 0:429446fe396d | 140 | |
mikl_andre | 0:429446fe396d | 141 | void unsolicited_callback(d7a_msg_t** uns) |
mikl_andre | 0:429446fe396d | 142 | { |
mikl_andre | 0:429446fe396d | 143 | PRINT("UNSOLICITED MESSAGE:\r\n"); |
mikl_andre | 0:429446fe396d | 144 | d7a_print_msg(uns); |
mikl_andre | 0:429446fe396d | 145 | d7a_free_msg(uns); |
mikl_andre | 0:429446fe396d | 146 | } |
mikl_andre | 0:429446fe396d | 147 | |
mikl_andre | 0:429446fe396d | 148 | // callbacks structure |
mikl_andre | 0:429446fe396d | 149 | const d7a_callbacks_t callbacks = { |
mikl_andre | 0:429446fe396d | 150 | .write_file = write_file_callback, // If NULL you cannot declare files |
mikl_andre | 0:429446fe396d | 151 | .read_file = read_file_callback, // If NULL you cannot declare files |
mikl_andre | 0:429446fe396d | 152 | .notif_done = notif_done_callback, |
mikl_andre | 0:429446fe396d | 153 | .unsolicited_msg = unsolicited_callback, |
mikl_andre | 0:429446fe396d | 154 | }; |
mikl_andre | 0:429446fe396d | 155 | |
mikl_andre | 0:429446fe396d | 156 | // Com configuration for the DASH7 shield |
mikl_andre | 0:429446fe396d | 157 | const d7a_com_config_t shield_config = { |
mikl_andre | 0:429446fe396d | 158 | .tx = D10, |
mikl_andre | 0:429446fe396d | 159 | .rx = D2, |
mikl_andre | 0:429446fe396d | 160 | .rts = D13, |
mikl_andre | 0:429446fe396d | 161 | .cts = D9, |
mikl_andre | 0:429446fe396d | 162 | .rx_buffer_size = 512, |
mikl_andre | 0:429446fe396d | 163 | }; |
mikl_andre | 0:429446fe396d | 164 | |
mikl_andre | 0:429446fe396d | 165 | |
mikl_andre | 0:429446fe396d | 166 | // Check parameters to see if data should be send |
mikl_andre | 0:429446fe396d | 167 | static bool report_needed(sensor_config_t* cfg, int32_t value, int32_t last_value, uint32_t last_report_time) |
mikl_andre | 0:429446fe396d | 168 | { |
mikl_andre | 0:429446fe396d | 169 | switch (cfg->report_type) |
mikl_andre | 0:429446fe396d | 170 | { |
mikl_andre | 0:429446fe396d | 171 | case REPORT_ALWAYS: |
mikl_andre | 0:429446fe396d | 172 | // Send a report at each measure |
mikl_andre | 0:429446fe396d | 173 | IPRINT("Notif cause 1\r\n"); |
mikl_andre | 0:429446fe396d | 174 | return true; |
mikl_andre | 0:429446fe396d | 175 | case REPORT_ON_DIFFERENCE: |
mikl_andre | 0:429446fe396d | 176 | // Send a report when the difference between the last reported measure and the current mesure is greater than max_diff |
mikl_andre | 0:429446fe396d | 177 | if (abs(last_value - value) >= cfg->max_diff) |
mikl_andre | 0:429446fe396d | 178 | { |
mikl_andre | 0:429446fe396d | 179 | IPRINT("Notif cause 2 last:%d new:%d max_diff:%d\r\n", last_value, value, cfg->max_diff); |
mikl_andre | 0:429446fe396d | 180 | return true; |
mikl_andre | 0:429446fe396d | 181 | } |
mikl_andre | 0:429446fe396d | 182 | break; |
mikl_andre | 0:429446fe396d | 183 | case REPORT_ON_THRESHOLD: |
mikl_andre | 0:429446fe396d | 184 | // Send a report when crossing a threshold |
mikl_andre | 0:429446fe396d | 185 | if ( (value >= cfg->threshold_high && last_value < cfg->threshold_high) |
mikl_andre | 0:429446fe396d | 186 | || (value <= cfg->threshold_low && last_value > cfg->threshold_low) |
mikl_andre | 0:429446fe396d | 187 | || (value < cfg->threshold_high && last_value >= cfg->threshold_high) |
mikl_andre | 0:429446fe396d | 188 | || (value > cfg->threshold_low && last_value <= cfg->threshold_low)) |
mikl_andre | 0:429446fe396d | 189 | { |
mikl_andre | 0:429446fe396d | 190 | IPRINT("Notif cause 3 last:%d new:%d th:%d tl:%d\r\n", last_value, value, cfg->threshold_high, cfg->threshold_low); |
mikl_andre | 0:429446fe396d | 191 | return true; |
mikl_andre | 0:429446fe396d | 192 | } |
mikl_andre | 0:429446fe396d | 193 | break; |
mikl_andre | 0:429446fe396d | 194 | default: |
mikl_andre | 0:429446fe396d | 195 | break; |
mikl_andre | 0:429446fe396d | 196 | } |
mikl_andre | 0:429446fe396d | 197 | |
mikl_andre | 0:429446fe396d | 198 | // Send a report if it's been more than max_period since the last report |
mikl_andre | 0:429446fe396d | 199 | if (((last_report_time/1000) >= cfg->max_period) && (cfg->max_period != 0)) |
mikl_andre | 0:429446fe396d | 200 | { |
mikl_andre | 0:429446fe396d | 201 | IPRINT("Notif cause 4 max_period:%d time:%d\r\n", cfg->max_period, last_report_time); |
mikl_andre | 0:429446fe396d | 202 | return true; |
mikl_andre | 0:429446fe396d | 203 | } |
mikl_andre | 0:429446fe396d | 204 | |
mikl_andre | 0:429446fe396d | 205 | return false; |
mikl_andre | 0:429446fe396d | 206 | } |
mikl_andre | 0:429446fe396d | 207 | |
mikl_andre | 0:429446fe396d | 208 | // Initialisation of the sensor thread's context |
mikl_andre | 0:429446fe396d | 209 | #define SENSOR_THREAD_CTX(_name,_vfid,_cfid,_read_func,_nb_values) \ |
mikl_andre | 0:429446fe396d | 210 | int32_t _name##_last_report[_nb_values];\ |
mikl_andre | 0:429446fe396d | 211 | int32_t _name##_current_value[_nb_values];\ |
mikl_andre | 0:429446fe396d | 212 | sensor_thread_ctx_t _name##_thread_ctx = {\ |
mikl_andre | 0:429446fe396d | 213 | .nb_values = _nb_values,\ |
mikl_andre | 0:429446fe396d | 214 | .data_size = _nb_values * sizeof(int32_t),\ |
mikl_andre | 0:429446fe396d | 215 | .read_value = _read_func,\ |
mikl_andre | 0:429446fe396d | 216 | .last_report_value = (int32_t*)&_name##_last_report,\ |
mikl_andre | 0:429446fe396d | 217 | .current_value = (int32_t*)&_name##_current_value,\ |
mikl_andre | 0:429446fe396d | 218 | .last_report_time = 0,\ |
mikl_andre | 0:429446fe396d | 219 | .value_file_id = _vfid,\ |
mikl_andre | 0:429446fe396d | 220 | .cfg_file_id = _cfid\ |
mikl_andre | 0:429446fe396d | 221 | } |
mikl_andre | 0:429446fe396d | 222 | |
mikl_andre | 0:429446fe396d | 223 | |
mikl_andre | 0:429446fe396d | 224 | SENSOR_THREAD_CTX(mag, MAG_VALUE_FILE_ID, MAG_CFG_FILE_ID, mag_get_value, 3); |
mikl_andre | 0:429446fe396d | 225 | SENSOR_THREAD_CTX(acc, ACC_VALUE_FILE_ID, ACC_CFG_FILE_ID, acc_get_value, 3); |
mikl_andre | 0:429446fe396d | 226 | SENSOR_THREAD_CTX(gyr, GYR_VALUE_FILE_ID, GYR_CFG_FILE_ID, gyr_get_value, 3); |
mikl_andre | 0:429446fe396d | 227 | SENSOR_THREAD_CTX(pre, PRE_VALUE_FILE_ID, PRE_CFG_FILE_ID, pre_get_value, 1); |
mikl_andre | 0:429446fe396d | 228 | SENSOR_THREAD_CTX(hum, HUM_VALUE_FILE_ID, HUM_CFG_FILE_ID, hum_get_value, 1); |
mikl_andre | 0:429446fe396d | 229 | SENSOR_THREAD_CTX(tem1, TEM1_VALUE_FILE_ID, TEM1_CFG_FILE_ID, tem1_get_value, 1); |
mikl_andre | 0:429446fe396d | 230 | SENSOR_THREAD_CTX(tem2, TEM2_VALUE_FILE_ID, TEM2_CFG_FILE_ID, tem2_get_value, 1); |
mikl_andre | 0:429446fe396d | 231 | |
mikl_andre | 0:429446fe396d | 232 | // ----------------------------------------------- |
mikl_andre | 0:429446fe396d | 233 | // Threads |
mikl_andre | 0:429446fe396d | 234 | // ----------------------------------------------- |
mikl_andre | 0:429446fe396d | 235 | void sensor_thread(const void* p) |
mikl_andre | 0:429446fe396d | 236 | { |
mikl_andre | 0:429446fe396d | 237 | FPRINT("(id:0x%08x)\r\n", osThreadGetId()); |
mikl_andre | 0:429446fe396d | 238 | d7a_msg_t** resp = NULL; |
mikl_andre | 0:429446fe396d | 239 | |
mikl_andre | 0:429446fe396d | 240 | // Get thread context |
mikl_andre | 0:429446fe396d | 241 | sensor_thread_ctx_t* th_ctx = (sensor_thread_ctx_t*)p; |
mikl_andre | 0:429446fe396d | 242 | |
mikl_andre | 0:429446fe396d | 243 | // Force a first notification |
mikl_andre | 0:429446fe396d | 244 | bool first_notif = true; |
mikl_andre | 0:429446fe396d | 245 | |
mikl_andre | 0:429446fe396d | 246 | // Retrieve notification config from local file |
mikl_andre | 0:429446fe396d | 247 | fs_read_file(th_ctx->cfg_file_id, 0, sizeof(sensor_config_t), (uint8_t*)&(th_ctx->cfg)); |
mikl_andre | 0:429446fe396d | 248 | |
mikl_andre | 0:429446fe396d | 249 | // Declare the config file to allow it to be accessed via the modem |
mikl_andre | 0:429446fe396d | 250 | d7a_declare(th_ctx->cfg_file_id, VOLATILE, RW_RW, sizeof(sensor_config_t), sizeof(sensor_config_t)); |
mikl_andre | 0:429446fe396d | 251 | |
mikl_andre | 0:429446fe396d | 252 | // Create a file on the modem to store and notify the sensor value |
mikl_andre | 0:429446fe396d | 253 | d7a_create(th_ctx->value_file_id, VOLATILE, RW_R, th_ctx->data_size, th_ctx->data_size, D7A_NOTIFICATION_FULL, D7A_ITF_REPORT_CHECKED); |
mikl_andre | 0:429446fe396d | 254 | |
mikl_andre | 0:429446fe396d | 255 | while (true) |
mikl_andre | 0:429446fe396d | 256 | { |
mikl_andre | 0:429446fe396d | 257 | // Read the sensor values |
mikl_andre | 0:429446fe396d | 258 | bool err = th_ctx->read_value(th_ctx->current_value); |
mikl_andre | 0:429446fe396d | 259 | |
mikl_andre | 0:429446fe396d | 260 | ASSERT(!err, "Failed to read sensor value for FID: %d\r\n", th_ctx->value_file_id); |
mikl_andre | 0:429446fe396d | 261 | |
mikl_andre | 0:429446fe396d | 262 | // Check if data should be send |
mikl_andre | 0:429446fe396d | 263 | for (uint8_t i = 0; i < th_ctx->nb_values; i++) |
mikl_andre | 0:429446fe396d | 264 | { |
mikl_andre | 0:429446fe396d | 265 | if (report_needed(&(th_ctx->cfg), |
mikl_andre | 0:429446fe396d | 266 | th_ctx->current_value[i], |
mikl_andre | 0:429446fe396d | 267 | th_ctx->last_report_value[i], |
mikl_andre | 0:429446fe396d | 268 | th_ctx->last_report_time) || first_notif) |
mikl_andre | 0:429446fe396d | 269 | { |
mikl_andre | 0:429446fe396d | 270 | first_notif = false; |
mikl_andre | 0:429446fe396d | 271 | |
mikl_andre | 0:429446fe396d | 272 | PRINT("NOTIFY %3d: ", th_ctx->value_file_id); |
mikl_andre | 0:429446fe396d | 273 | for (uint8_t i = 0; i < th_ctx->nb_values; i++) |
mikl_andre | 0:429446fe396d | 274 | { |
mikl_andre | 0:429446fe396d | 275 | PRINT("%9ld ", (int32_t)th_ctx->current_value[i]); |
mikl_andre | 0:429446fe396d | 276 | } |
mikl_andre | 0:429446fe396d | 277 | PRINT("\r\n"); |
mikl_andre | 0:429446fe396d | 278 | |
mikl_andre | 0:429446fe396d | 279 | // Send data to the modem |
mikl_andre | 0:429446fe396d | 280 | resp = d7a_write(th_ctx->value_file_id, 0, th_ctx->data_size, (uint8_t*)th_ctx->current_value); |
mikl_andre | 0:429446fe396d | 281 | d7a_free_msg(resp); |
mikl_andre | 0:429446fe396d | 282 | |
mikl_andre | 0:429446fe396d | 283 | // Update last report value |
mikl_andre | 0:429446fe396d | 284 | memcpy(th_ctx->last_report_value, th_ctx->current_value, th_ctx->data_size); |
mikl_andre | 0:429446fe396d | 285 | // Reset last report time |
mikl_andre | 0:429446fe396d | 286 | th_ctx->last_report_time = 0; |
mikl_andre | 0:429446fe396d | 287 | break; |
mikl_andre | 0:429446fe396d | 288 | } |
mikl_andre | 0:429446fe396d | 289 | } |
mikl_andre | 0:429446fe396d | 290 | |
mikl_andre | 0:429446fe396d | 291 | // Update last report time |
mikl_andre | 0:429446fe396d | 292 | th_ctx->last_report_time += th_ctx->cfg.period; |
mikl_andre | 0:429446fe396d | 293 | |
mikl_andre | 0:429446fe396d | 294 | // Wait for period |
mikl_andre | 0:429446fe396d | 295 | Thread::wait(th_ctx->cfg.period); |
mikl_andre | 0:429446fe396d | 296 | } |
mikl_andre | 0:429446fe396d | 297 | } |
mikl_andre | 0:429446fe396d | 298 | |
mikl_andre | 0:429446fe396d | 299 | void file_modified_thread(const void *p) |
mikl_andre | 0:429446fe396d | 300 | { |
mikl_andre | 0:429446fe396d | 301 | FPRINT("(id:0x%08x)\r\n", osThreadGetId()); |
mikl_andre | 0:429446fe396d | 302 | |
mikl_andre | 0:429446fe396d | 303 | while (true) |
mikl_andre | 0:429446fe396d | 304 | { |
mikl_andre | 0:429446fe396d | 305 | // Wait for a file modified event |
mikl_andre | 0:429446fe396d | 306 | osEvent evt = fm_queue.get(); |
mikl_andre | 0:429446fe396d | 307 | |
mikl_andre | 0:429446fe396d | 308 | // Retrieve FID of modified file |
mikl_andre | 0:429446fe396d | 309 | uint8_t fid = (uint8_t)(uint32_t)evt.value.p; |
mikl_andre | 0:429446fe396d | 310 | |
mikl_andre | 0:429446fe396d | 311 | PRINT("File %d has been modified\r\n", fid); |
mikl_andre | 0:429446fe396d | 312 | |
mikl_andre | 0:429446fe396d | 313 | switch (fid) |
mikl_andre | 0:429446fe396d | 314 | { |
mikl_andre | 0:429446fe396d | 315 | // If a configuration file has been modified, update the context |
mikl_andre | 0:429446fe396d | 316 | case MAG_CFG_FILE_ID: |
mikl_andre | 0:429446fe396d | 317 | fs_read_file(fid, 0, sizeof(sensor_config_t), (uint8_t*)&(mag_thread_ctx.cfg)); |
mikl_andre | 0:429446fe396d | 318 | break; |
mikl_andre | 0:429446fe396d | 319 | case ACC_CFG_FILE_ID: |
mikl_andre | 0:429446fe396d | 320 | fs_read_file(fid, 0, sizeof(sensor_config_t), (uint8_t*)&(acc_thread_ctx.cfg)); |
mikl_andre | 0:429446fe396d | 321 | break; |
mikl_andre | 0:429446fe396d | 322 | case GYR_CFG_FILE_ID: |
mikl_andre | 0:429446fe396d | 323 | fs_read_file(fid, 0, sizeof(sensor_config_t), (uint8_t*)&(gyr_thread_ctx.cfg)); |
mikl_andre | 0:429446fe396d | 324 | break; |
mikl_andre | 0:429446fe396d | 325 | case PRE_CFG_FILE_ID: |
mikl_andre | 0:429446fe396d | 326 | fs_read_file(fid, 0, sizeof(sensor_config_t), (uint8_t*)&(pre_thread_ctx.cfg)); |
mikl_andre | 0:429446fe396d | 327 | break; |
mikl_andre | 0:429446fe396d | 328 | case HUM_CFG_FILE_ID: |
mikl_andre | 0:429446fe396d | 329 | fs_read_file(fid, 0, sizeof(sensor_config_t), (uint8_t*)&(hum_thread_ctx.cfg)); |
mikl_andre | 0:429446fe396d | 330 | break; |
mikl_andre | 0:429446fe396d | 331 | case TEM1_CFG_FILE_ID: |
mikl_andre | 0:429446fe396d | 332 | fs_read_file(fid, 0, sizeof(sensor_config_t), (uint8_t*)&(tem1_thread_ctx.cfg)); |
mikl_andre | 0:429446fe396d | 333 | break; |
mikl_andre | 0:429446fe396d | 334 | case TEM2_CFG_FILE_ID: |
mikl_andre | 0:429446fe396d | 335 | fs_read_file(fid, 0, sizeof(sensor_config_t), (uint8_t*)&(tem2_thread_ctx.cfg)); |
mikl_andre | 0:429446fe396d | 336 | break; |
mikl_andre | 0:429446fe396d | 337 | case SIMUL_FILE_ID: |
mikl_andre | 0:429446fe396d | 338 | uint32_t divider; |
mikl_andre | 0:429446fe396d | 339 | // Retreive the simulation parameter from local file |
mikl_andre | 0:429446fe396d | 340 | fs_read_file(SIMUL_FILE_ID, 0, sizeof(uint32_t), (uint8_t*)÷r); |
mikl_andre | 0:429446fe396d | 341 | // Update the simulation parameters |
mikl_andre | 0:429446fe396d | 342 | update_simul_param(divider); |
mikl_andre | 0:429446fe396d | 343 | PRINT("Simulation Divider is Now %d\r\n", divider); |
mikl_andre | 0:429446fe396d | 344 | break; |
mikl_andre | 0:429446fe396d | 345 | default: |
mikl_andre | 0:429446fe396d | 346 | break; |
mikl_andre | 0:429446fe396d | 347 | } |
mikl_andre | 0:429446fe396d | 348 | } |
mikl_andre | 0:429446fe396d | 349 | } |
mikl_andre | 0:429446fe396d | 350 | |
mikl_andre | 0:429446fe396d | 351 | void button_user_thread(const void *p) |
mikl_andre | 0:429446fe396d | 352 | { |
mikl_andre | 0:429446fe396d | 353 | FPRINT("(id:0x%08x)\r\n", osThreadGetId()); |
mikl_andre | 0:429446fe396d | 354 | |
mikl_andre | 0:429446fe396d | 355 | uint8_t alarm = 255; |
mikl_andre | 0:429446fe396d | 356 | d7a_msg_t** resp = NULL; |
mikl_andre | 0:429446fe396d | 357 | |
mikl_andre | 0:429446fe396d | 358 | // Create the alarm file |
mikl_andre | 0:429446fe396d | 359 | //d7a_create(ALARM_FILE_ID, VOLATILE, RW_R, sizeof(uint8_t), sizeof(uint8_t), D7A_NOTIFICATION_FULL, D7A_ITF_SINGLE); |
mikl_andre | 0:429446fe396d | 360 | |
mikl_andre | 0:429446fe396d | 361 | // Update it with the default value |
mikl_andre | 0:429446fe396d | 362 | //resp = d7a_write(ALARM_FILE_ID, 0, sizeof(uint8_t), (uint8_t*)&alarm); |
mikl_andre | 0:429446fe396d | 363 | //d7a_free_msg(resp); |
mikl_andre | 0:429446fe396d | 364 | |
mikl_andre | 0:429446fe396d | 365 | while (true) |
mikl_andre | 0:429446fe396d | 366 | { |
mikl_andre | 0:429446fe396d | 367 | // Wait for button press |
mikl_andre | 0:429446fe396d | 368 | button_user.wait(); |
mikl_andre | 0:429446fe396d | 369 | |
mikl_andre | 0:429446fe396d | 370 | // Toggle alarm state |
mikl_andre | 0:429446fe396d | 371 | alarm = !alarm; |
mikl_andre | 0:429446fe396d | 372 | |
mikl_andre | 0:429446fe396d | 373 | PRINT("BUTTON ALARM %d\r\n", alarm); |
mikl_andre | 0:429446fe396d | 374 | #if 1 // Switch between Notify and Distant Read/Write example |
mikl_andre | 0:429446fe396d | 375 | |
mikl_andre | 0:429446fe396d | 376 | // Send alarm state to the modem |
mikl_andre | 0:429446fe396d | 377 | //resp = d7a_write(ALARM_FILE_ID, 0, sizeof(uint8_t), (uint8_t*)&alarm); |
mikl_andre | 0:429446fe396d | 378 | //WARNING(!resp[0]->err, "BUTTON ALARM ERR %d\r\n", resp[0]->err); |
mikl_andre | 0:429446fe396d | 379 | //d7a_free_msg(resp); |
mikl_andre | 0:429446fe396d | 380 | #else |
mikl_andre | 0:429446fe396d | 381 | // Distant device that I want to acceed |
mikl_andre | 0:429446fe396d | 382 | #if 0 // Unicast / Broadcast |
mikl_andre | 0:429446fe396d | 383 | // Unicast |
mikl_andre | 0:429446fe396d | 384 | d7a_addressee_t target = { |
mikl_andre | 0:429446fe396d | 385 | // Access Class |
mikl_andre | 0:429446fe396d | 386 | .xcl.byte = D7A_XCL_ENDPOINT_LO, |
mikl_andre | 0:429446fe396d | 387 | // Type of security you want to use |
mikl_andre | 0:429446fe396d | 388 | .ctrl.bf.nls = D7A_NLS_AES_CCM_64, |
mikl_andre | 0:429446fe396d | 389 | // Type of ID |
mikl_andre | 0:429446fe396d | 390 | .ctrl.bf.idf = D7A_ID_UID, |
mikl_andre | 0:429446fe396d | 391 | // Device ID |
mikl_andre | 0:429446fe396d | 392 | .id = { 0x00, 0x1B, 0xC5, 0x0C, 0x70, 0x00, 0x07, 0xA3 }, |
mikl_andre | 0:429446fe396d | 393 | }; |
mikl_andre | 0:429446fe396d | 394 | #else |
mikl_andre | 0:429446fe396d | 395 | // Broadcast |
mikl_andre | 0:429446fe396d | 396 | d7a_addressee_t target = { |
mikl_andre | 0:429446fe396d | 397 | // Access Class |
mikl_andre | 0:429446fe396d | 398 | .xcl.byte = D7A_XCL_ENDPOINT_LO, |
mikl_andre | 0:429446fe396d | 399 | // Type of security you want to use |
mikl_andre | 0:429446fe396d | 400 | .ctrl.bf.nls = D7A_NLS_AES_CCM_64, |
mikl_andre | 0:429446fe396d | 401 | // Type of ID |
mikl_andre | 0:429446fe396d | 402 | .ctrl.bf.idf = D7A_ID_NBID, |
mikl_andre | 0:429446fe396d | 403 | // Maximum number of responses (1-32) |
mikl_andre | 0:429446fe396d | 404 | .id[0] = D7A_NBID(8), |
mikl_andre | 0:429446fe396d | 405 | }; |
mikl_andre | 0:429446fe396d | 406 | #endif |
mikl_andre | 0:429446fe396d | 407 | |
mikl_andre | 0:429446fe396d | 408 | #if 1 // Read / Write |
mikl_andre | 0:429446fe396d | 409 | // Read example |
mikl_andre | 0:429446fe396d | 410 | //resp = d7a_read(MAG_CFG_FILE_ID, 12, 5, &target, D7A_ITF_ONESHOT); |
mikl_andre | 0:429446fe396d | 411 | resp = d7a_read(ALARM_FILE_ID, 0, 1, NULL, &target, D7A_ITF_ONESHOT); |
mikl_andre | 0:429446fe396d | 412 | #else |
mikl_andre | 0:429446fe396d | 413 | // Write example |
mikl_andre | 0:429446fe396d | 414 | uint8_t v = 0x01; |
mikl_andre | 0:429446fe396d | 415 | resp = d7a_write(ALARM_FILE_ID, 0, 1, &v, NULL, &target, D7A_ITF_ONESHOT); |
mikl_andre | 0:429446fe396d | 416 | #endif |
mikl_andre | 0:429446fe396d | 417 | // Check received response(s) |
mikl_andre | 0:429446fe396d | 418 | d7a_print_msg(resp); |
mikl_andre | 0:429446fe396d | 419 | |
mikl_andre | 0:429446fe396d | 420 | PRINT("Resp done.\r\n"); |
mikl_andre | 0:429446fe396d | 421 | d7a_free_msg(resp); |
mikl_andre | 0:429446fe396d | 422 | #endif |
mikl_andre | 0:429446fe396d | 423 | |
mikl_andre | 0:429446fe396d | 424 | |
mikl_andre | 0:429446fe396d | 425 | } |
mikl_andre | 0:429446fe396d | 426 | } |
mikl_andre | 0:429446fe396d | 427 | |
mikl_andre | 0:429446fe396d | 428 | |
mikl_andre | 0:429446fe396d | 429 | /*** Main function ------------------------------------------------------------- ***/ |
mikl_andre | 0:429446fe396d | 430 | int main() |
mikl_andre | 0:429446fe396d | 431 | { |
mikl_andre | 0:429446fe396d | 432 | PinName DBG_LED = D12; |
mikl_andre | 0:429446fe396d | 433 | |
mikl_andre | 0:429446fe396d | 434 | // Go to sleep when idle |
mikl_andre | 0:429446fe396d | 435 | //rtos_attach_idle_hook(sleep); |
mikl_andre | 0:429446fe396d | 436 | |
mikl_andre | 0:429446fe396d | 437 | // Start & initialize |
mikl_andre | 0:429446fe396d | 438 | DBG_OPEN(DBG_LED); |
mikl_andre | 0:429446fe396d | 439 | PRINT("\r\n--- Starting new run ---\r\n"); |
mikl_andre | 0:429446fe396d | 440 | FPRINT("(id:0x%08x)\r\n", osThreadGetId()); |
mikl_andre | 0:429446fe396d | 441 | |
mikl_andre | 0:429446fe396d | 442 | DigitalOut myled(DBG_LED); |
mikl_andre | 0:429446fe396d | 443 | DebouncedInterrupt user_interrupt(USER_BUTTON); |
mikl_andre | 0:429446fe396d | 444 | user_interrupt.attach(button_push_isr, IRQ_FALL, 200, true); |
mikl_andre | 0:429446fe396d | 445 | myled = 1; |
mikl_andre | 0:429446fe396d | 446 | |
mikl_andre | 0:429446fe396d | 447 | extern uint16_t const os_maxtaskrun; |
mikl_andre | 0:429446fe396d | 448 | //IPRINT("Max user threads: %d\r\n", os_maxtaskrun-1-9); |
mikl_andre | 0:429446fe396d | 449 | #if 0 |
mikl_andre | 0:429446fe396d | 450 | d7a_open(&shield_config, A3, &callbacks); |
mikl_andre | 0:429446fe396d | 451 | d7a_modem_print_infos(); |
mikl_andre | 0:429446fe396d | 452 | |
mikl_andre | 0:429446fe396d | 453 | // Create the revision file for the Dash7board |
mikl_andre | 0:429446fe396d | 454 | d7a_create(65, PERMANENT, RW_R, sizeof(d7a_revision_t), sizeof(d7a_revision_t), D7A_NOTIFICATION_FULL, D7A_ITF_REPORT_CHECKED); |
mikl_andre | 0:429446fe396d | 455 | // Notify revision |
mikl_andre | 0:429446fe396d | 456 | d7a_msg_t** resp = d7a_write(65, 0, sizeof(d7a_revision_t), (uint8_t*)&f_dev_rev); |
mikl_andre | 0:429446fe396d | 457 | d7a_free_msg(resp); |
mikl_andre | 0:429446fe396d | 458 | #endif |
mikl_andre | 0:429446fe396d | 459 | |
mikl_andre | 0:429446fe396d | 460 | #if _SENSORS_SIMU_ |
mikl_andre | 0:429446fe396d | 461 | PRINT("(Simulated sensors)\r\n"); |
mikl_andre | 0:429446fe396d | 462 | uint32_t divider; |
mikl_andre | 0:429446fe396d | 463 | |
mikl_andre | 0:429446fe396d | 464 | // Retreive the simulation parameter from local file |
mikl_andre | 0:429446fe396d | 465 | fs_read_file(SIMUL_FILE_ID, 0, sizeof(uint32_t), (uint8_t*)÷r); |
mikl_andre | 0:429446fe396d | 466 | |
mikl_andre | 0:429446fe396d | 467 | // Update the simulation parameters |
mikl_andre | 0:429446fe396d | 468 | update_simul_param(divider); |
mikl_andre | 0:429446fe396d | 469 | |
mikl_andre | 0:429446fe396d | 470 | // Declare the simulation parameter file |
mikl_andre | 0:429446fe396d | 471 | //d7a_declare(SIMUL_FILE_ID, PERMANENT, RW_RW, sizeof(sensor_config_t), sizeof(sensor_config_t)); |
mikl_andre | 0:429446fe396d | 472 | |
mikl_andre | 0:429446fe396d | 473 | #else |
mikl_andre | 0:429446fe396d | 474 | // Open I2C and initialise the sensors |
mikl_andre | 0:429446fe396d | 475 | DevI2C ext_i2c(D14, D15); |
mikl_andre | 0:429446fe396d | 476 | |
mikl_andre | 0:429446fe396d | 477 | #if (_HUM_EN_ || _TEM1_EN_) |
mikl_andre | 0:429446fe396d | 478 | humidity_sensor = new HTS221(ext_i2c); |
mikl_andre | 0:429446fe396d | 479 | ASSERT(Init_HTS221(humidity_sensor), "Failed to init HTS221\r\n"); |
mikl_andre | 0:429446fe396d | 480 | temp_sensor1 = humidity_sensor; |
mikl_andre | 0:429446fe396d | 481 | #endif // _TEM_EN_ |
mikl_andre | 0:429446fe396d | 482 | #if _MAG_EN_ |
mikl_andre | 0:429446fe396d | 483 | magnetometer = new LIS3MDL(ext_i2c); |
mikl_andre | 0:429446fe396d | 484 | ASSERT(Init_LIS3MDL(magnetometer), "Failed to init LIS3MDL\r\n"); |
mikl_andre | 0:429446fe396d | 485 | #endif // _MAG_EN_ |
mikl_andre | 0:429446fe396d | 486 | #if (_ACC_EN_ || _GYR_EN_) |
mikl_andre | 0:429446fe396d | 487 | accelerometer = new LSM6DS0(ext_i2c); |
mikl_andre | 0:429446fe396d | 488 | ASSERT(Init_LSM6DS0(accelerometer), "Failed to init LSM6DS0\r\n"); |
mikl_andre | 0:429446fe396d | 489 | gyroscope = accelerometer; |
mikl_andre | 0:429446fe396d | 490 | #endif // _ACC_EN_ || _GYR_EN_ |
mikl_andre | 0:429446fe396d | 491 | #if (_PRE_EN_ || _TEM2_EN_) |
mikl_andre | 0:429446fe396d | 492 | pressure_sensor = new LPS25H(ext_i2c); |
mikl_andre | 0:429446fe396d | 493 | ASSERT(Init_LPS25H(pressure_sensor), "Failed to init LPS25H\r\n"); |
mikl_andre | 0:429446fe396d | 494 | temp_sensor2 = pressure_sensor; |
mikl_andre | 0:429446fe396d | 495 | #endif // _PRE_EN_ |
mikl_andre | 0:429446fe396d | 496 | |
mikl_andre | 0:429446fe396d | 497 | #endif // _SENSORS_SIMU_ |
mikl_andre | 0:429446fe396d | 498 | |
mikl_andre | 0:429446fe396d | 499 | // File modified thread |
mikl_andre | 0:429446fe396d | 500 | Thread fm_th(file_modified_thread); |
mikl_andre | 0:429446fe396d | 501 | |
mikl_andre | 0:429446fe396d | 502 | #if _MAG_EN_ |
mikl_andre | 0:429446fe396d | 503 | Thread mag_th(sensor_thread, (void*)&mag_thread_ctx, osPriorityNormal, DEFAULT_STACK_SIZE*2); |
mikl_andre | 0:429446fe396d | 504 | #endif // _MAG_EN_ |
mikl_andre | 0:429446fe396d | 505 | #if _ACC_EN_ |
mikl_andre | 0:429446fe396d | 506 | Thread acc_th(sensor_thread, (void*)&acc_thread_ctx, osPriorityNormal, DEFAULT_STACK_SIZE*2); |
mikl_andre | 0:429446fe396d | 507 | #endif // _ACC_EN_ |
mikl_andre | 0:429446fe396d | 508 | #if _GYR_EN_ |
mikl_andre | 0:429446fe396d | 509 | Thread gyr_th(sensor_thread, (void*)&gyr_thread_ctx, osPriorityNormal, DEFAULT_STACK_SIZE*2); |
mikl_andre | 0:429446fe396d | 510 | #endif // _GYR_EN_ |
mikl_andre | 0:429446fe396d | 511 | #if _PRE_EN_ |
mikl_andre | 0:429446fe396d | 512 | Thread pre_th(sensor_thread, (void*)&pre_thread_ctx, osPriorityNormal, DEFAULT_STACK_SIZE*2); |
mikl_andre | 0:429446fe396d | 513 | #endif // _PRE_EN_ |
mikl_andre | 0:429446fe396d | 514 | #if _HUM_EN_ |
mikl_andre | 0:429446fe396d | 515 | Thread hum_th(sensor_thread, (void*)&hum_thread_ctx, osPriorityNormal, DEFAULT_STACK_SIZE*2); |
mikl_andre | 0:429446fe396d | 516 | #endif // _HUM_EN_ |
mikl_andre | 0:429446fe396d | 517 | #if _TEM1_EN_ |
mikl_andre | 0:429446fe396d | 518 | Thread tem1_th(sensor_thread, (void*)&tem1_thread_ctx, osPriorityNormal, DEFAULT_STACK_SIZE*2); |
mikl_andre | 0:429446fe396d | 519 | #endif // _TEM1_EN_ |
mikl_andre | 0:429446fe396d | 520 | #if _TEM2_EN_ |
mikl_andre | 0:429446fe396d | 521 | Thread tem2_th(sensor_thread, (void*)&tem2_thread_ctx, osPriorityNormal, DEFAULT_STACK_SIZE*2); |
mikl_andre | 0:429446fe396d | 522 | #endif // _TEM2_EN_ |
mikl_andre | 0:429446fe396d | 523 | |
mikl_andre | 0:429446fe396d | 524 | // For button irq |
mikl_andre | 0:429446fe396d | 525 | Thread but_th(button_user_thread, NULL, osPriorityNormal, DEFAULT_STACK_SIZE*4); |
mikl_andre | 0:429446fe396d | 526 | |
mikl_andre | 0:429446fe396d | 527 | // Set main task to lowest priority |
mikl_andre | 0:429446fe396d | 528 | osThreadSetPriority(osThreadGetId(), osPriorityIdle); |
mikl_andre | 0:429446fe396d | 529 | while(true) |
mikl_andre | 0:429446fe396d | 530 | { |
mikl_andre | 0:429446fe396d | 531 | // Wait to avoid beeing stuck in loop |
mikl_andre | 0:429446fe396d | 532 | Thread::wait(200); |
mikl_andre | 0:429446fe396d | 533 | myled = !myled; |
mikl_andre | 0:429446fe396d | 534 | } |
mikl_andre | 0:429446fe396d | 535 | } |