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