read and push

Dependencies:   X_NUCLEO_IKS01A1 MLX90614 d7a_1x wizzi-utils

Fork of D7A_1x_demo_sensors_OS5 by WizziLab

Committer:
shawe
Date:
Mon Feb 27 08:46:36 2017 +0000
Revision:
16:ad7842fcd376
Parent:
15:f8e5805c696c
Add config for small nucleo;

Who changed what in which revision?

UserRevisionLine numberNew 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 #include "mbed.h"
Jeej 0:7e1fdc4d6e1c 31 #include "rtos.h"
Jeej 0:7e1fdc4d6e1c 32 #include "rtos_idle.h"
Jeej 0:7e1fdc4d6e1c 33 #include "d7a.h"
Jeej 0:7e1fdc4d6e1c 34 #include "sensors.h"
Jeej 0:7e1fdc4d6e1c 35 #include "simul.h"
Jeej 0:7e1fdc4d6e1c 36 #include "dbg.h"
Jeej 0:7e1fdc4d6e1c 37 #include "DebouncedInterrupt.h"
Jeej 0:7e1fdc4d6e1c 38 #include "files.h"
shawe 10:3d3dfc12f674 39 #include "MLX90614.h"
shawe 10:3d3dfc12f674 40 #include "DevI2C.h"
Jeej 0:7e1fdc4d6e1c 41
shawe 16:ad7842fcd376 42 #if defined(TARGET_STM32L152RE)
shawe 16:ad7842fcd376 43 #define D7A_PIN_TX (D10)
shawe 16:ad7842fcd376 44 #define D7A_PIN_RX (D2)
shawe 16:ad7842fcd376 45 #define D7A_PIN_RTS (D13)
shawe 16:ad7842fcd376 46 #define D7A_PIN_CTS (D9)
shawe 16:ad7842fcd376 47 #define D7A_PIN_RESET (A3)
shawe 16:ad7842fcd376 48 #define DEBUG_LED (LED1)
shawe 16:ad7842fcd376 49 #define DEBUG_BUTTON (USER_BUTTON)
shawe 16:ad7842fcd376 50 #define SENSOR_I2C_SDA (D14)
shawe 16:ad7842fcd376 51 #define SENSOR_I2C_SCL (D15)
shawe 16:ad7842fcd376 52 #define VOLT_PIN (A0)
shawe 16:ad7842fcd376 53
shawe 16:ad7842fcd376 54 #elif defined(TARGET_STM32L432KC)
shawe 16:ad7842fcd376 55 // -----------------------------------------------
shawe 16:ad7842fcd376 56 // Hardware configuration for sh2050
shawe 16:ad7842fcd376 57 // -----------------------------------------------
shawe 16:ad7842fcd376 58 #define D7A_PIN_TX (D5)
shawe 16:ad7842fcd376 59 #define D7A_PIN_RX (D4)
shawe 16:ad7842fcd376 60 #define D7A_PIN_RTS (D11)
shawe 16:ad7842fcd376 61 #define D7A_PIN_CTS (D10)
shawe 16:ad7842fcd376 62 #define D7A_PIN_RESET (D12)
shawe 16:ad7842fcd376 63 #define DEBUG_LED (D13) // LED1
shawe 16:ad7842fcd376 64 #define DEBUG_BUTTON (D9)
shawe 16:ad7842fcd376 65 #define SENSOR_I2C_SDA (D0)
shawe 16:ad7842fcd376 66 #define SENSOR_I2C_SCL (D1)
shawe 16:ad7842fcd376 67 // TODO Check which pin to use on the small board for voltage stuff
shawe 16:ad7842fcd376 68 #define VOLT_PIN (A0)
shawe 16:ad7842fcd376 69
shawe 16:ad7842fcd376 70 #else
shawe 16:ad7842fcd376 71 #error "Please choose or add the right platform."
shawe 16:ad7842fcd376 72 #endif
yordan 8:01f0225408cf 73
shawe 16:ad7842fcd376 74 #define DGB_LED_BLINK_PERIOD (500)
shawe 10:3d3dfc12f674 75 #define _TEM1_EN_ (1)
shawe 10:3d3dfc12f674 76 #define _VOLTAGE_EN_ (1)
shawe 10:3d3dfc12f674 77 #if (_VOLTAGE_EN_ == 1)
shawe 16:ad7842fcd376 78 AnalogIn volt_pin(VOLT_PIN);
shawe 10:3d3dfc12f674 79 #endif
yordan 7:8de29807f970 80
shawe 16:ad7842fcd376 81 MLX90614 *mlxSensor;
Jeej 0:7e1fdc4d6e1c 82 Semaphore button_user(0);
Jeej 0:7e1fdc4d6e1c 83 Semaphore thread_ready(0);
Jeej 0:7e1fdc4d6e1c 84
Jeej 0:7e1fdc4d6e1c 85 // Interrupt Service Routine on button press.
Jeej 0:7e1fdc4d6e1c 86 void button_push_isr( void )
Jeej 0:7e1fdc4d6e1c 87 {
Jeej 0:7e1fdc4d6e1c 88 button_user.release();
Jeej 0:7e1fdc4d6e1c 89 }
Jeej 0:7e1fdc4d6e1c 90
Jeej 0:7e1fdc4d6e1c 91 // file modified queue
Jeej 0:7e1fdc4d6e1c 92 Queue<void, 8> fm_queue;
Jeej 0:7e1fdc4d6e1c 93
Jeej 0:7e1fdc4d6e1c 94 // -----------------------------------------------
Jeej 0:7e1fdc4d6e1c 95 // callbacks
Jeej 0:7e1fdc4d6e1c 96 // -----------------------------------------------
Jeej 0:7e1fdc4d6e1c 97 /**
Jeej 0:7e1fdc4d6e1c 98 Write data into a file.
Jeej 0:7e1fdc4d6e1c 99
Jeej 0:7e1fdc4d6e1c 100 @param const uint8_t File ID
Jeej 0:7e1fdc4d6e1c 101 @param const uint16_t Offset from start of data
Jeej 0:7e1fdc4d6e1c 102 @param const uint16_t Size of data to be written
Jeej 0:7e1fdc4d6e1c 103 @param const uint8_t* const Pointer to the data to write
Jeej 0:7e1fdc4d6e1c 104 @return uint32_t Size of written data
Jeej 0:7e1fdc4d6e1c 105 */
Jeej 0:7e1fdc4d6e1c 106 uint32_t write_file_callback(const uint8_t file_id,
Jeej 0:7e1fdc4d6e1c 107 const uint16_t offset,
Jeej 0:7e1fdc4d6e1c 108 const uint16_t size,
Jeej 0:7e1fdc4d6e1c 109 const uint8_t* const content)
Jeej 0:7e1fdc4d6e1c 110 {
Jeej 0:7e1fdc4d6e1c 111 uint32_t ret = 0;
Jeej 0:7e1fdc4d6e1c 112
Jeej 0:7e1fdc4d6e1c 113 IPRINT("Write file %d offset:%d size:%d\r\n", file_id, offset, size);
Jeej 0:7e1fdc4d6e1c 114
Jeej 0:7e1fdc4d6e1c 115 ret = fs_write_file(file_id, offset, size, content);
Jeej 0:7e1fdc4d6e1c 116
Jeej 0:7e1fdc4d6e1c 117 WARNING(ret, "File %d not found\r\n", file_id);
Jeej 0:7e1fdc4d6e1c 118
Jeej 0:7e1fdc4d6e1c 119 // Indicate that the file has been modified
Jeej 0:7e1fdc4d6e1c 120 fm_queue.put((void*)file_id);
Jeej 0:7e1fdc4d6e1c 121
Jeej 0:7e1fdc4d6e1c 122 return ret;
Jeej 0:7e1fdc4d6e1c 123 }
Jeej 0:7e1fdc4d6e1c 124
Jeej 0:7e1fdc4d6e1c 125 /**
Jeej 0:7e1fdc4d6e1c 126 Read data from a file.
Jeej 0:7e1fdc4d6e1c 127
Jeej 0:7e1fdc4d6e1c 128 @param const uint8_t File ID
Jeej 0:7e1fdc4d6e1c 129 @param const uint16_t Offset from start of data
Jeej 0:7e1fdc4d6e1c 130 @param const uint16_t Size of data to be read
Jeej 0:7e1fdc4d6e1c 131 @param const uint8_t* const Pointer to the reading buffer
Jeej 0:7e1fdc4d6e1c 132 @return uint32_t Size of read data
Jeej 0:7e1fdc4d6e1c 133 */
Jeej 0:7e1fdc4d6e1c 134 uint32_t read_file_callback(const uint8_t file_id,
Jeej 0:7e1fdc4d6e1c 135 const uint16_t offset,
Jeej 0:7e1fdc4d6e1c 136 const uint16_t size,
Jeej 0:7e1fdc4d6e1c 137 uint8_t* buf)
Jeej 0:7e1fdc4d6e1c 138 {
shawe 10:3d3dfc12f674 139 PRINT("Read file %d offset:%d size:%d\r\n", file_id, offset, size);
shawe 10:3d3dfc12f674 140 uint32_t ret = fs_read_file(file_id, offset, size, buf);
Jeej 0:7e1fdc4d6e1c 141 WARNING(ret, "File %d not found\r\n", file_id);
Jeej 0:7e1fdc4d6e1c 142 return ret;
Jeej 0:7e1fdc4d6e1c 143 }
Jeej 0:7e1fdc4d6e1c 144
Jeej 0:7e1fdc4d6e1c 145 /**
Jeej 0:7e1fdc4d6e1c 146 Called when a notification is finished
Jeej 0:7e1fdc4d6e1c 147
Jeej 0:7e1fdc4d6e1c 148 @param const uint8_t File ID
Jeej 0:7e1fdc4d6e1c 149 @param const uint8_t Error code
Jeej 0:7e1fdc4d6e1c 150 @return void
Jeej 0:7e1fdc4d6e1c 151 */
Jeej 0:7e1fdc4d6e1c 152 void notif_done_callback(const uint8_t file_id, const uint8_t error)
Jeej 0:7e1fdc4d6e1c 153 {
Jeej 0:7e1fdc4d6e1c 154 PRINT("Notif FID %d done. err %d\r\n", file_id, error);
Jeej 0:7e1fdc4d6e1c 155 }
Jeej 0:7e1fdc4d6e1c 156
Jeej 0:7e1fdc4d6e1c 157 void unsolicited_callback(d7a_msg_t** uns)
Jeej 0:7e1fdc4d6e1c 158 {
Jeej 0:7e1fdc4d6e1c 159 PRINT("UNSOLICITED MESSAGE:\r\n");
Jeej 0:7e1fdc4d6e1c 160 d7a_print_msg(uns);
Jeej 0:7e1fdc4d6e1c 161 d7a_free_msg(uns);
Jeej 0:7e1fdc4d6e1c 162 }
Jeej 0:7e1fdc4d6e1c 163
Jeej 0:7e1fdc4d6e1c 164 // callbacks structure
Jeej 0:7e1fdc4d6e1c 165 const d7a_callbacks_t callbacks = {
Jeej 0:7e1fdc4d6e1c 166 .write_file = write_file_callback, // If NULL you cannot declare files
Jeej 0:7e1fdc4d6e1c 167 .read_file = read_file_callback, // If NULL you cannot declare files
Jeej 0:7e1fdc4d6e1c 168 .notif_done = notif_done_callback,
Jeej 0:7e1fdc4d6e1c 169 .unsolicited_msg = unsolicited_callback,
Jeej 0:7e1fdc4d6e1c 170 };
Jeej 0:7e1fdc4d6e1c 171
Jeej 0:7e1fdc4d6e1c 172 // Com configuration for the DASH7 shield
Jeej 0:7e1fdc4d6e1c 173 const d7a_com_config_t shield_config = {
Jeej 1:711fb7d8127b 174 .tx = D7A_PIN_TX,
Jeej 1:711fb7d8127b 175 .rx = D7A_PIN_RX,
Jeej 1:711fb7d8127b 176 .rts = D7A_PIN_RTS,
Jeej 1:711fb7d8127b 177 .cts = D7A_PIN_CTS,
Jeej 0:7e1fdc4d6e1c 178 };
Jeej 0:7e1fdc4d6e1c 179
Jeej 0:7e1fdc4d6e1c 180 // Check parameters to see if data should be send
Jeej 0:7e1fdc4d6e1c 181 static bool report_needed(sensor_config_t* cfg, int32_t value, int32_t last_value, uint32_t last_report_time)
Jeej 0:7e1fdc4d6e1c 182 {
Jeej 0:7e1fdc4d6e1c 183 switch (cfg->report_type)
Jeej 0:7e1fdc4d6e1c 184 {
Jeej 0:7e1fdc4d6e1c 185 case REPORT_ALWAYS:
Jeej 0:7e1fdc4d6e1c 186 // Send a report at each measure
Jeej 0:7e1fdc4d6e1c 187 IPRINT("Notif cause 1\r\n");
Jeej 0:7e1fdc4d6e1c 188 return true;
Jeej 0:7e1fdc4d6e1c 189 case REPORT_ON_DIFFERENCE:
Jeej 0:7e1fdc4d6e1c 190 // Send a report when the difference between the last reported measure and the current mesure is greater than max_diff
Jeej 0:7e1fdc4d6e1c 191 if (abs(last_value - value) >= cfg->max_diff)
Jeej 0:7e1fdc4d6e1c 192 {
Jeej 0:7e1fdc4d6e1c 193 IPRINT("Notif cause 2 last:%d new:%d max_diff:%d\r\n", last_value, value, cfg->max_diff);
Jeej 0:7e1fdc4d6e1c 194 return true;
Jeej 0:7e1fdc4d6e1c 195 }
Jeej 0:7e1fdc4d6e1c 196 break;
Jeej 0:7e1fdc4d6e1c 197 case REPORT_ON_THRESHOLD:
Jeej 0:7e1fdc4d6e1c 198 // Send a report when crossing a threshold
Jeej 0:7e1fdc4d6e1c 199 if ( (value >= cfg->threshold_high && last_value < cfg->threshold_high)
Jeej 0:7e1fdc4d6e1c 200 || (value <= cfg->threshold_low && last_value > cfg->threshold_low)
Jeej 0:7e1fdc4d6e1c 201 || (value < cfg->threshold_high && last_value >= cfg->threshold_high)
Jeej 0:7e1fdc4d6e1c 202 || (value > cfg->threshold_low && last_value <= cfg->threshold_low))
Jeej 0:7e1fdc4d6e1c 203 {
Jeej 0:7e1fdc4d6e1c 204 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 205 return true;
Jeej 0:7e1fdc4d6e1c 206 }
Jeej 0:7e1fdc4d6e1c 207 break;
Jeej 0:7e1fdc4d6e1c 208 default:
Jeej 0:7e1fdc4d6e1c 209 break;
Jeej 0:7e1fdc4d6e1c 210 }
Jeej 0:7e1fdc4d6e1c 211
Jeej 0:7e1fdc4d6e1c 212 // Send a report if it's been more than max_period since the last report
Jeej 0:7e1fdc4d6e1c 213 if (((last_report_time/1000) >= cfg->max_period) && (cfg->max_period != 0))
Jeej 0:7e1fdc4d6e1c 214 {
Jeej 0:7e1fdc4d6e1c 215 IPRINT("Notif cause 4 max_period:%d time:%d\r\n", cfg->max_period, last_report_time);
Jeej 0:7e1fdc4d6e1c 216 return true;
Jeej 0:7e1fdc4d6e1c 217 }
Jeej 0:7e1fdc4d6e1c 218
Jeej 0:7e1fdc4d6e1c 219 return false;
Jeej 0:7e1fdc4d6e1c 220 }
Jeej 0:7e1fdc4d6e1c 221
yordan 7:8de29807f970 222 // -----------------------------------------------
yordan 7:8de29807f970 223 // Sensor Threads
yordan 7:8de29807f970 224 // -----------------------------------------------
yordan 7:8de29807f970 225 typedef struct
yordan 7:8de29807f970 226 {
yordan 7:8de29807f970 227 // Number of data fields
yordan 7:8de29807f970 228 uint32_t nb_values;
yordan 7:8de29807f970 229 // Total size of data
yordan 7:8de29807f970 230 uint32_t data_size;
yordan 7:8de29807f970 231 // Read value function
yordan 7:8de29807f970 232 bool (*read_value)(int32_t*);
yordan 7:8de29807f970 233 // Last reported value
yordan 7:8de29807f970 234 int32_t* last_report_value;
yordan 7:8de29807f970 235 // Current measured value
yordan 7:8de29807f970 236 int32_t* current_value;
yordan 7:8de29807f970 237
yordan 7:8de29807f970 238 // File ID of the sensor value file
yordan 7:8de29807f970 239 uint8_t value_file_id;
yordan 7:8de29807f970 240 // Sensor configuration file ID
yordan 7:8de29807f970 241 uint8_t cfg_file_id;
yordan 7:8de29807f970 242 // Sensor configuration context
yordan 7:8de29807f970 243 sensor_config_t cfg;
yordan 7:8de29807f970 244
yordan 7:8de29807f970 245 } sensor_thread_ctx_t;
yordan 7:8de29807f970 246
yordan 7:8de29807f970 247 sensor_thread_ctx_t* g_thread_ctx;
yordan 7:8de29807f970 248
yordan 7:8de29807f970 249 // Initialisation of the sensor thread's context
yordan 7:8de29807f970 250 #define SENSOR_THREAD_CTX(_name,_vfid,_cfid,_read_func,_nb_values) \
yordan 7:8de29807f970 251 int32_t _name##_last_report[_nb_values];\
yordan 7:8de29807f970 252 int32_t _name##_current_value[_nb_values];\
yordan 7:8de29807f970 253 sensor_thread_ctx_t _name##_thread_ctx = {\
yordan 7:8de29807f970 254 .nb_values = _nb_values,\
yordan 7:8de29807f970 255 .data_size = _nb_values * sizeof(int32_t),\
yordan 7:8de29807f970 256 .read_value = _read_func,\
yordan 7:8de29807f970 257 .last_report_value = (int32_t*)&_name##_last_report,\
yordan 7:8de29807f970 258 .current_value = (int32_t*)&_name##_current_value,\
yordan 7:8de29807f970 259 .value_file_id = _vfid,\
yordan 7:8de29807f970 260 .cfg_file_id = _cfid\
yordan 7:8de29807f970 261 }
yordan 7:8de29807f970 262
yordan 7:8de29807f970 263 __inline int32_t float2_to_int(float v)
yordan 7:8de29807f970 264 {
yordan 7:8de29807f970 265 return (int32_t)(v*100);
yordan 7:8de29807f970 266 }
yordan 8:01f0225408cf 267
yordan 7:8de29807f970 268 bool tem1_get_value(int32_t* buf)
yordan 7:8de29807f970 269 {
yordan 8:01f0225408cf 270 #if (_TEM1_EN_ == 0)
yordan 7:8de29807f970 271 return simul_sensor_value(buf, 1, 1100, 3900);
yordan 8:01f0225408cf 272 #elif (_TEM1_EN_ == 1)
shawe 16:ad7842fcd376 273 float ambient = mlxSensor->ambientTemp();
shawe 16:ad7842fcd376 274 float object = mlxSensor->objectTemp();
shawe 10:3d3dfc12f674 275 PRINT("Got %f || %f\r\n", ambient, object);
shawe 10:3d3dfc12f674 276 buf[0] = float2_to_int(object);
shawe 10:3d3dfc12f674 277 buf[1] = float2_to_int(ambient);
yordan 8:01f0225408cf 278 return false;
yordan 7:8de29807f970 279 #endif
yordan 7:8de29807f970 280 }
shawe 10:3d3dfc12f674 281 SENSOR_THREAD_CTX(tem1, TEM1_VALUE_FILE_ID, TEM1_CFG_FILE_ID, tem1_get_value, 2);
Jeej 0:7e1fdc4d6e1c 282
shawe 10:3d3dfc12f674 283 bool volt_get_value(int32_t* buf)
yordan 8:01f0225408cf 284 {
shawe 10:3d3dfc12f674 285 #if (_VOLTAGE_EN_ == 0)
shawe 10:3d3dfc12f674 286 return simul_sensor_value(buf, 1, 0, 1000);
shawe 10:3d3dfc12f674 287 #elif (_VOLTAGE_EN_ == 1)
shawe 10:3d3dfc12f674 288 float voltage = volt_pin*1000;
shawe 10:3d3dfc12f674 289 PRINT("Voltage value %f\r\n", voltage);
shawe 10:3d3dfc12f674 290 buf[0] = float2_to_int(voltage);
yordan 8:01f0225408cf 291 return false;
yordan 8:01f0225408cf 292 #else
yordan 8:01f0225408cf 293 return false;
yordan 8:01f0225408cf 294 #endif
yordan 8:01f0225408cf 295 }
shawe 10:3d3dfc12f674 296 SENSOR_THREAD_CTX(volt, VOLT_VALUE_FILE_ID, VOLT_CFG_FILE_ID, volt_get_value, 1);
yordan 8:01f0225408cf 297
Jeej 0:7e1fdc4d6e1c 298
Jeej 0:7e1fdc4d6e1c 299 void sensor_thread()
Jeej 0:7e1fdc4d6e1c 300 {
Jeej 1:711fb7d8127b 301 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 1:711fb7d8127b 302
Jeej 0:7e1fdc4d6e1c 303 // Get thread context
Jeej 0:7e1fdc4d6e1c 304 sensor_thread_ctx_t* th_ctx = g_thread_ctx;
Jeej 4:8ac150ec1532 305
Jeej 0:7e1fdc4d6e1c 306 d7a_msg_t** resp = NULL;
Jeej 0:7e1fdc4d6e1c 307 uint32_t last_report_time = 0;
Jeej 0:7e1fdc4d6e1c 308
Jeej 0:7e1fdc4d6e1c 309 // Force a first notification
Jeej 0:7e1fdc4d6e1c 310 bool first_notif = true;
Jeej 0:7e1fdc4d6e1c 311
Jeej 0:7e1fdc4d6e1c 312 // Retrieve notification config from local file
Jeej 0:7e1fdc4d6e1c 313 fs_read_file(th_ctx->cfg_file_id, 0, sizeof(sensor_config_t), (uint8_t*)&(th_ctx->cfg));
Jeej 0:7e1fdc4d6e1c 314
Jeej 0:7e1fdc4d6e1c 315 // Declare the config file to allow it to be accessed via the modem
Jeej 0:7e1fdc4d6e1c 316 d7a_declare(th_ctx->cfg_file_id, VOLATILE, RW_RW, sizeof(sensor_config_t), sizeof(sensor_config_t));
Jeej 0:7e1fdc4d6e1c 317
Jeej 0:7e1fdc4d6e1c 318 // Create a file on the modem to store and notify the sensor value
Jeej 0:7e1fdc4d6e1c 319 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 320
Jeej 4:8ac150ec1532 321 thread_ready.release();
Jeej 4:8ac150ec1532 322
Jeej 0:7e1fdc4d6e1c 323 while (true)
Jeej 0:7e1fdc4d6e1c 324 {
Jeej 0:7e1fdc4d6e1c 325 // Read the sensor values
Jeej 0:7e1fdc4d6e1c 326 bool err = th_ctx->read_value(th_ctx->current_value);
Jeej 0:7e1fdc4d6e1c 327
Jeej 1:711fb7d8127b 328 ASSERT(!err, "Failed to read sensor value for FID: %d\r\n", th_ctx->value_file_id);
Jeej 0:7e1fdc4d6e1c 329
Jeej 0:7e1fdc4d6e1c 330 // Check if data should be send
Jeej 0:7e1fdc4d6e1c 331 for (uint8_t i = 0; i < th_ctx->nb_values; i++)
Jeej 0:7e1fdc4d6e1c 332 {
Jeej 0:7e1fdc4d6e1c 333 if (report_needed(&(th_ctx->cfg),
Jeej 0:7e1fdc4d6e1c 334 th_ctx->current_value[i],
Jeej 0:7e1fdc4d6e1c 335 th_ctx->last_report_value[i],
Jeej 0:7e1fdc4d6e1c 336 last_report_time) || first_notif)
Jeej 0:7e1fdc4d6e1c 337 {
Jeej 0:7e1fdc4d6e1c 338 first_notif = false;
Jeej 0:7e1fdc4d6e1c 339
Jeej 0:7e1fdc4d6e1c 340 PRINT("NOTIFY %3d: ", th_ctx->value_file_id);
Jeej 0:7e1fdc4d6e1c 341 for (uint8_t i = 0; i < th_ctx->nb_values; i++)
Jeej 0:7e1fdc4d6e1c 342 {
Jeej 0:7e1fdc4d6e1c 343 PRINT("%9ld ", (int32_t)th_ctx->current_value[i]);
Jeej 0:7e1fdc4d6e1c 344 }
Jeej 0:7e1fdc4d6e1c 345 PRINT("\r\n");
Jeej 0:7e1fdc4d6e1c 346
Jeej 0:7e1fdc4d6e1c 347 // Send data to the modem
Jeej 0:7e1fdc4d6e1c 348 resp = d7a_write(th_ctx->value_file_id, 0, th_ctx->data_size, (uint8_t*)th_ctx->current_value);
Jeej 0:7e1fdc4d6e1c 349 d7a_free_msg(resp);
Jeej 0:7e1fdc4d6e1c 350
Jeej 0:7e1fdc4d6e1c 351 // Update last report value
Jeej 0:7e1fdc4d6e1c 352 memcpy(th_ctx->last_report_value, th_ctx->current_value, th_ctx->data_size);
Jeej 0:7e1fdc4d6e1c 353 // Reset last report time
Jeej 0:7e1fdc4d6e1c 354 last_report_time = 0;
Jeej 0:7e1fdc4d6e1c 355 break;
Jeej 0:7e1fdc4d6e1c 356 }
Jeej 0:7e1fdc4d6e1c 357 }
Jeej 0:7e1fdc4d6e1c 358
Jeej 0:7e1fdc4d6e1c 359 // Update last report time
Jeej 0:7e1fdc4d6e1c 360 last_report_time += th_ctx->cfg.period;
Jeej 0:7e1fdc4d6e1c 361
Jeej 0:7e1fdc4d6e1c 362 // Wait for period
Jeej 0:7e1fdc4d6e1c 363 Thread::wait(th_ctx->cfg.period);
Jeej 0:7e1fdc4d6e1c 364 }
Jeej 0:7e1fdc4d6e1c 365 }
Jeej 0:7e1fdc4d6e1c 366
Jeej 0:7e1fdc4d6e1c 367 void file_modified_thread()
Jeej 0:7e1fdc4d6e1c 368 {
Jeej 0:7e1fdc4d6e1c 369 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:7e1fdc4d6e1c 370
Jeej 0:7e1fdc4d6e1c 371 while (true)
Jeej 0:7e1fdc4d6e1c 372 {
Jeej 0:7e1fdc4d6e1c 373 // Wait for a file modified event
shawe 10:3d3dfc12f674 374 osEvent evt = fm_queue.get();
Jeej 0:7e1fdc4d6e1c 375 // Retrieve FID of modified file
Jeej 0:7e1fdc4d6e1c 376 uint8_t fid = (uint8_t)(uint32_t)evt.value.p;
Jeej 0:7e1fdc4d6e1c 377 PRINT("File %d has been modified\r\n", fid);
Jeej 0:7e1fdc4d6e1c 378
Jeej 0:7e1fdc4d6e1c 379 switch (fid)
Jeej 0:7e1fdc4d6e1c 380 {
Jeej 0:7e1fdc4d6e1c 381 // If a configuration file has been modified, update the context
shawe 10:3d3dfc12f674 382 case VOLT_CFG_FILE_ID:
shawe 10:3d3dfc12f674 383 fs_read_file(fid, 0, sizeof(sensor_config_t), (uint8_t*)&(volt_thread_ctx.cfg));
Jeej 0:7e1fdc4d6e1c 384 break;
Jeej 0:7e1fdc4d6e1c 385 case TEM1_CFG_FILE_ID:
Jeej 0:7e1fdc4d6e1c 386 fs_read_file(fid, 0, sizeof(sensor_config_t), (uint8_t*)&(tem1_thread_ctx.cfg));
shawe 10:3d3dfc12f674 387 break;
Jeej 0:7e1fdc4d6e1c 388 default:
Jeej 0:7e1fdc4d6e1c 389 break;
Jeej 0:7e1fdc4d6e1c 390 }
Jeej 0:7e1fdc4d6e1c 391 }
Jeej 0:7e1fdc4d6e1c 392 }
Jeej 0:7e1fdc4d6e1c 393
Jeej 0:7e1fdc4d6e1c 394 void button_user_thread()
Jeej 0:7e1fdc4d6e1c 395 {
Jeej 0:7e1fdc4d6e1c 396 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:7e1fdc4d6e1c 397
Jeej 0:7e1fdc4d6e1c 398 uint8_t alarm = 255;
Jeej 0:7e1fdc4d6e1c 399 d7a_msg_t** resp = NULL;
Jeej 0:7e1fdc4d6e1c 400
Jeej 0:7e1fdc4d6e1c 401 // Create the alarm file
Jeej 0:7e1fdc4d6e1c 402 d7a_create(ALARM_FILE_ID, VOLATILE, RW_R, sizeof(uint8_t), sizeof(uint8_t), D7A_NOTIFICATION_FULL, D7A_ITF_SINGLE);
Jeej 0:7e1fdc4d6e1c 403
Jeej 0:7e1fdc4d6e1c 404 // Update it with the default value
Jeej 0:7e1fdc4d6e1c 405 resp = d7a_write(ALARM_FILE_ID, 0, sizeof(uint8_t), (uint8_t*)&alarm);
Jeej 0:7e1fdc4d6e1c 406 d7a_free_msg(resp);
Jeej 0:7e1fdc4d6e1c 407
Jeej 0:7e1fdc4d6e1c 408 while (true)
Jeej 0:7e1fdc4d6e1c 409 {
Jeej 0:7e1fdc4d6e1c 410 // Wait for button press
Jeej 0:7e1fdc4d6e1c 411 button_user.wait();
Jeej 0:7e1fdc4d6e1c 412
Jeej 0:7e1fdc4d6e1c 413 // Toggle alarm state
Jeej 0:7e1fdc4d6e1c 414 alarm = !alarm;
Jeej 0:7e1fdc4d6e1c 415
Jeej 0:7e1fdc4d6e1c 416 PRINT("BUTTON ALARM %d\r\n", alarm);
Jeej 0:7e1fdc4d6e1c 417 #if 1 // Switch between Notify and Distant Read/Write example
Jeej 0:7e1fdc4d6e1c 418 // Send alarm state to the modem
Jeej 0:7e1fdc4d6e1c 419 resp = d7a_write(ALARM_FILE_ID, 0, sizeof(uint8_t), (uint8_t*)&alarm);
Jeej 0:7e1fdc4d6e1c 420 WARNING(!resp[0]->err, "BUTTON ALARM ERR %d\r\n", resp[0]->err);
Jeej 0:7e1fdc4d6e1c 421 d7a_free_msg(resp);
Jeej 0:7e1fdc4d6e1c 422 #else
Jeej 0:7e1fdc4d6e1c 423 // Distant device that I want to acceed
Jeej 0:7e1fdc4d6e1c 424 #if 0 // Unicast / Broadcast
Jeej 0:7e1fdc4d6e1c 425 // Unicast
Jeej 0:7e1fdc4d6e1c 426 d7a_addressee_t target = {
Jeej 0:7e1fdc4d6e1c 427 // Access Class
Jeej 0:7e1fdc4d6e1c 428 .xcl.byte = D7A_XCL_ENDPOINT_NO,
Jeej 0:7e1fdc4d6e1c 429 // Type of security you want to use
Jeej 0:7e1fdc4d6e1c 430 .ctrl.bf.nls = D7A_NLS_AES_CCM_64,
Jeej 0:7e1fdc4d6e1c 431 // Type of ID
Jeej 0:7e1fdc4d6e1c 432 .ctrl.bf.idf = D7A_ID_UID,
Jeej 0:7e1fdc4d6e1c 433 // Device ID
Jeej 0:7e1fdc4d6e1c 434 .id = { 0x00, 0x1B, 0xC5, 0x0C, 0x70, 0x00, 0x07, 0xA3 },
Jeej 0:7e1fdc4d6e1c 435 };
Jeej 0:7e1fdc4d6e1c 436 #else
Jeej 0:7e1fdc4d6e1c 437 // Broadcast
Jeej 0:7e1fdc4d6e1c 438 d7a_addressee_t target = {
Jeej 0:7e1fdc4d6e1c 439 // Access Class
Jeej 0:7e1fdc4d6e1c 440 .xcl.byte = D7A_XCL_ENDPOINT_NO,
Jeej 0:7e1fdc4d6e1c 441 // Type of security you want to use
Jeej 0:7e1fdc4d6e1c 442 .ctrl.bf.nls = D7A_NLS_AES_CCM_64,
Jeej 0:7e1fdc4d6e1c 443 // Type of ID
Jeej 0:7e1fdc4d6e1c 444 .ctrl.bf.idf = D7A_ID_NBID,
Jeej 0:7e1fdc4d6e1c 445 // Maximum number of responses (1-32)
Jeej 0:7e1fdc4d6e1c 446 .id[0] = D7A_NBID(8),
Jeej 0:7e1fdc4d6e1c 447 };
Jeej 0:7e1fdc4d6e1c 448 #endif
Jeej 0:7e1fdc4d6e1c 449
Jeej 0:7e1fdc4d6e1c 450 #if 1 // Read / Write
Jeej 0:7e1fdc4d6e1c 451 // Read example
Jeej 0:7e1fdc4d6e1c 452 //resp = d7a_read(MAG_CFG_FILE_ID, 12, 5, &target, D7A_ITF_ONESHOT);
Jeej 0:7e1fdc4d6e1c 453 resp = d7a_read(ALARM_FILE_ID, 0, 1, NULL, &target, D7A_ITF_ONESHOT);
Jeej 0:7e1fdc4d6e1c 454 #else
Jeej 0:7e1fdc4d6e1c 455 // Write example
Jeej 0:7e1fdc4d6e1c 456 uint8_t v = 0x01;
Jeej 0:7e1fdc4d6e1c 457 resp = d7a_write(ALARM_FILE_ID, 0, 1, &v, NULL, &target, D7A_ITF_ONESHOT);
Jeej 0:7e1fdc4d6e1c 458 #endif
Jeej 0:7e1fdc4d6e1c 459 // Check received response(s)
Jeej 0:7e1fdc4d6e1c 460 d7a_print_msg(resp);
Jeej 0:7e1fdc4d6e1c 461
Jeej 0:7e1fdc4d6e1c 462 PRINT("Resp done.\r\n");
Jeej 0:7e1fdc4d6e1c 463 d7a_free_msg(resp);
Jeej 0:7e1fdc4d6e1c 464 #endif
Jeej 0:7e1fdc4d6e1c 465 }
Jeej 0:7e1fdc4d6e1c 466 }
Jeej 0:7e1fdc4d6e1c 467
Jeej 0:7e1fdc4d6e1c 468 /*** Main function ------------------------------------------------------------- ***/
Jeej 0:7e1fdc4d6e1c 469 int main()
Jeej 0:7e1fdc4d6e1c 470 {
Jeej 0:7e1fdc4d6e1c 471 // Start & initialize
Jeej 3:5f2917933ece 472 DBG_OPEN(DEBUG_LED);
Jeej 0:7e1fdc4d6e1c 473 PRINT("\r\n--- Starting new run ---\r\n");
Jeej 0:7e1fdc4d6e1c 474
Jeej 0:7e1fdc4d6e1c 475 extern uint16_t const os_maxtaskrun;
Jeej 0:7e1fdc4d6e1c 476 //IPRINT("Max user threads: %d\r\n", os_maxtaskrun-1-9);
Jeej 0:7e1fdc4d6e1c 477
Jeej 1:711fb7d8127b 478 d7a_open(&shield_config, D7A_PIN_RESET, &callbacks);
Jeej 0:7e1fdc4d6e1c 479 d7a_modem_print_infos();
Jeej 0:7e1fdc4d6e1c 480
Jeej 0:7e1fdc4d6e1c 481 // Create the revision file for the Dash7board
Jeej 0:7e1fdc4d6e1c 482 d7a_create(65, PERMANENT, RW_R, sizeof(d7a_revision_t), sizeof(d7a_revision_t), D7A_NOTIFICATION_FULL, D7A_ITF_REPORT_CHECKED);
Jeej 0:7e1fdc4d6e1c 483 // Notify revision
Jeej 0:7e1fdc4d6e1c 484 d7a_msg_t** resp = d7a_write(65, 0, sizeof(d7a_revision_t), (uint8_t*)&f_dev_rev);
Jeej 0:7e1fdc4d6e1c 485 d7a_free_msg(resp);
Jeej 0:7e1fdc4d6e1c 486
Jeej 0:7e1fdc4d6e1c 487 uint32_t divider;
Jeej 0:7e1fdc4d6e1c 488
Jeej 0:7e1fdc4d6e1c 489 // Retreive the simulation parameter from local file
Jeej 0:7e1fdc4d6e1c 490 fs_read_file(SIMUL_FILE_ID, 0, sizeof(uint32_t), (uint8_t*)&divider);
Jeej 0:7e1fdc4d6e1c 491
Jeej 0:7e1fdc4d6e1c 492 // Update the simulation parameters
Jeej 0:7e1fdc4d6e1c 493 simul_update_param(divider);
Jeej 0:7e1fdc4d6e1c 494
Jeej 0:7e1fdc4d6e1c 495 // Declare the simulation parameter file
Jeej 0:7e1fdc4d6e1c 496 d7a_declare(SIMUL_FILE_ID, PERMANENT, RW_RW, sizeof(sensor_config_t), sizeof(sensor_config_t));
Jeej 0:7e1fdc4d6e1c 497
shawe 10:3d3dfc12f674 498 #if (_TEM1_EN_ == 1)
yordan 8:01f0225408cf 499 // Open I2C and initialise the sensors
yordan 7:8de29807f970 500 DevI2C ext_i2c(SENSOR_I2C_SDA, SENSOR_I2C_SCL);
shawe 10:3d3dfc12f674 501 ext_i2c.frequency(100000);
shawe 16:ad7842fcd376 502 mlxSensor = new MLX90614(&ext_i2c);
yordan 8:01f0225408cf 503 #endif
yordan 8:01f0225408cf 504
Jeej 0:7e1fdc4d6e1c 505 osStatus status;
Jeej 0:7e1fdc4d6e1c 506
Jeej 0:7e1fdc4d6e1c 507 // Start sensors threads
Jeej 1:711fb7d8127b 508 #define THREAD_START(_name) Thread _name##_th(osPriorityNormal, 1024, NULL);\
Jeej 0:7e1fdc4d6e1c 509 g_thread_ctx = &_name##_thread_ctx;\
Jeej 0:7e1fdc4d6e1c 510 status = _name##_th.start(sensor_thread);\
Jeej 1:711fb7d8127b 511 ASSERT(status == osOK, "Failed to start ##_name## thread (err: %d)\r\n", status);\
Jeej 0:7e1fdc4d6e1c 512 thread_ready.wait();
Jeej 0:7e1fdc4d6e1c 513
yordan 8:01f0225408cf 514 #if (_TEM1_EN_ >= 0)
Jeej 0:7e1fdc4d6e1c 515 THREAD_START(tem1);
Jeej 0:7e1fdc4d6e1c 516 #endif // _TEM1_EN_
shawe 10:3d3dfc12f674 517
shawe 10:3d3dfc12f674 518 #if (_VOLTAGE_EN_ >=0)
shawe 10:3d3dfc12f674 519 THREAD_START(volt);
shawe 10:3d3dfc12f674 520 #endif
Jeej 0:7e1fdc4d6e1c 521
Jeej 0:7e1fdc4d6e1c 522 // File modified thread
Jeej 1:711fb7d8127b 523 Thread fm_th(osPriorityNormal, 512, NULL);
Jeej 1:711fb7d8127b 524 status = fm_th.start(file_modified_thread);
Jeej 1:711fb7d8127b 525 ASSERT(status == osOK, "Failed to start fm thread (err: %d)\r\n", status);
Jeej 0:7e1fdc4d6e1c 526
Jeej 1:711fb7d8127b 527 // For button
Jeej 3:5f2917933ece 528 #ifdef DEBUG_BUTTON
Jeej 3:5f2917933ece 529 DebouncedInterrupt user_interrupt(DEBUG_BUTTON);
yordan 5:ef4b5c422d3a 530 user_interrupt.attach(button_push_isr, IRQ_FALL, 500, true);
Jeej 1:711fb7d8127b 531
Jeej 1:711fb7d8127b 532 Thread but_th(osPriorityNormal, 512, NULL);
Jeej 1:711fb7d8127b 533 status = but_th.start(button_user_thread);
Jeej 1:711fb7d8127b 534 ASSERT(status == osOK, "Failed to start but thread (err: %d)\r\n", status);
Jeej 1:711fb7d8127b 535 #endif
yordan 5:ef4b5c422d3a 536
yordan 5:ef4b5c422d3a 537 #ifdef DGB_LED_BLINK_PERIOD
yordan 5:ef4b5c422d3a 538 DigitalOut my_led(DEBUG_LED);
yordan 5:ef4b5c422d3a 539 #endif
shawe 10:3d3dfc12f674 540
Jeej 0:7e1fdc4d6e1c 541 // Set main task to lowest priority
Jeej 0:7e1fdc4d6e1c 542 osThreadSetPriority(osThreadGetId(), osPriorityIdle);
Jeej 0:7e1fdc4d6e1c 543 while(true)
Jeej 0:7e1fdc4d6e1c 544 {
yordan 5:ef4b5c422d3a 545 #ifdef DGB_LED_BLINK_PERIOD
Jeej 0:7e1fdc4d6e1c 546 // Wait to avoid beeing stuck in loop
yordan 6:55244aef7c67 547 Thread::wait(DGB_LED_BLINK_PERIOD);
yordan 5:ef4b5c422d3a 548 my_led = !my_led;
yordan 5:ef4b5c422d3a 549 #else
Jeej 3:5f2917933ece 550 Thread::wait(osWaitForever);
yordan 5:ef4b5c422d3a 551 #endif
Jeej 0:7e1fdc4d6e1c 552 }
Jeej 0:7e1fdc4d6e1c 553 }