Wirepas SDK
ruuvi_evk/app.c
#include <stdio.h>
#include <string.h>
#include "api.h"
#include "tlv.h"
#include "app_scheduler.h"
#include "board.h"
#include "spi.h"
#include "power.h"
#include "bme280_wrapper.h"
#include "lis2dh12_wrapper.h"
#include "app_config.h"
#include "format_data.h"
/* Endpoints on which sensor data is sent. */
#define SENSOR_DATA_DST_ENDPOINT 11
#define SENSOR_DATA_SRC_ENDPOINT 11
/* State machine to manage sensors measurement start and read data.*/
typedef enum
{
SENSOR_TASK_STATE_START_MEAS,
SENSOR_TASK_STATE_SEND_DATA
} sensor_task_state_e;
/* State of the application.*/
sensor_task_state_e m_task_state;
/* Read sensors data. */
sensor_data_t m_sensor_data;
static bool ruuvi_spi_init(void)
{
spi_res_e res;
spi_conf_t conf;
/* Initialize LIS2DH12 Chip select pin. */
nrf_gpio_pin_dir_set(BOARD_SPI_LIS2DH12_CS_PIN, NRF_GPIO_PIN_DIR_OUTPUT);
nrf_gpio_cfg_output(BOARD_SPI_LIS2DH12_CS_PIN);
nrf_gpio_pin_set(BOARD_SPI_LIS2DH12_CS_PIN);
/* Initialize BME280 Chip select pin. */
nrf_gpio_pin_dir_set(BOARD_SPI_BME280_CS_PIN, NRF_GPIO_PIN_DIR_OUTPUT);
nrf_gpio_cfg_output(BOARD_SPI_BME280_CS_PIN);
nrf_gpio_pin_set(BOARD_SPI_BME280_CS_PIN);
/* Initialize SPI driver. */
conf.clock = 4000000;
res = SPI_init(&conf);
if ((res != SPI_RES_OK) && (res != SPI_RES_ALREADY_INITIALIZED))
{
return false;
}
return true;
}
static void send_data(sensor_data_t *data)
{
uint8_t buff[102];
int len = 102;
/* For now the only supported format is TLV */
len = format_data_tlv(buff, data, len);
/* Only send data if there is a route to the Sink. */
app_res_e res = lib_state->getRouteInfo(&route_info);
if (res == APP_RES_OK && route_info.state == APP_LIB_STATE_ROUTE_STATE_VALID
&& len != -1)
{
app_lib_data_to_send_t data_to_send;
data_to_send.bytes = (const uint8_t *) buff;
data_to_send.num_bytes = len;
data_to_send.src_endpoint = SENSOR_DATA_SRC_ENDPOINT;
data_to_send.dest_endpoint = SENSOR_DATA_DST_ENDPOINT;
data_to_send.qos = APP_LIB_DATA_QOS_HIGH;
data_to_send.delay = 0;
/* Send the data packet. */
lib_data->sendData(&data_to_send);
}
}
static uint32_t sensor_task()
{
const app_config_t * cfg = App_Config_get();
uint32_t time_to_run;
switch (m_task_state)
{
case SENSOR_TASK_STATE_START_MEAS:
{
m_task_state = SENSOR_TASK_STATE_SEND_DATA;
if(cfg->temperature_enable ||
cfg->humidity_enable ||
cfg->pressure_enable )
{
time_to_run = BME280_wrapper_startMeasurement();
}
if(cfg->accel_x_enable ||
cfg->accel_y_enable ||
cfg->accel_z_enable )
{
uint32_t lis2dh12_time_to_run;
lis2dh12_time_to_run = LIS2DH12_wrapper_startMeasurement();
if(lis2dh12_time_to_run > time_to_run)
{
time_to_run = lis2dh12_time_to_run;
}
}
break;
}
case SENSOR_TASK_STATE_SEND_DATA:
{
/* Counter is always enabled. Increment it each period. */
m_sensor_data.count++;
if (cfg->temperature_enable ||
cfg->humidity_enable ||
cfg->pressure_enable )
{
bme280_wrapper_measurement_t measurement;
BME280_wrapper_readMeasurement(&measurement);
m_sensor_data.temp = measurement.temperature;
m_sensor_data.press = measurement.pressure;
m_sensor_data.humi = measurement.humidity;
}
if(cfg->accel_x_enable ||
cfg->accel_y_enable ||
cfg->accel_z_enable )
{
lis2dh12_wrapper_measurement_t measurement;
LIS2DH12_wrapper_readMeasurement(&measurement);
m_sensor_data.acc_x = measurement.accel_x;
m_sensor_data.acc_y = measurement.accel_y;
m_sensor_data.acc_z = measurement.accel_z;
}
send_data(&m_sensor_data);
m_task_state = SENSOR_TASK_STATE_START_MEAS;
time_to_run = cfg->sensors_period_ms;
break;
}
default:
{
m_task_state = SENSOR_TASK_STATE_START_MEAS;
time_to_run = cfg->sensors_period_ms;
break;
}
}
return time_to_run;
}
static void on_config_update(void)
{
const app_config_t * cfg = App_Config_get();
if(cfg->sensors_period_ms == 0)
{
/* Cancel sensor task. Don't send sensor data anymore. */
}
else
{
/* Config changed, schedule Sensor task ASAP. */
}
}
void App_init(const app_global_functions_t * functions)
{
/* Basic configuration of the node with a unique node address. */
{
/*
* Could not configure the node.
* It should not happen except if one of the config value is invalid.
*/
return;
}
m_sensor_data.count = 0;
m_task_state = SENSOR_TASK_STATE_START_MEAS;
/* Initialize all the modules. */
App_Config_init(on_config_update);
ruuvi_spi_init();
BME280_wrapper_init();
LIS2DH12_wrapper_init();
/* Launch the sensor task. */
/*
* Start the stack.
* This is really important step, otherwise the stack will stay stopped and
* will not be part of any network. So the device will not be reachable
* without reflashing it
*/
lib_state->startStack();
}
BOARD_SPI_BME280_CS_PIN
#define BOARD_SPI_BME280_CS_PIN
Definition: board.h:25
SPI_ORDER_MSB
@ SPI_ORDER_MSB
Definition: spi.h:29
app_lib_data_to_send_t::tracking_id
app_lib_data_tracking_id_t tracking_id
Definition: wms_data.h:346
spi.h
app_res_e
app_res_e
Definition: wms_app.h:201
app_lib_data_to_send_t::src_endpoint
uint8_t src_endpoint
Definition: wms_data.h:352
APP_LIB_DATA_SEND_FLAG_NONE
@ APP_LIB_DATA_SEND_FLAG_NONE
Definition: wms_data.h:100
power.h
app_lib_data_to_send_t::dest_address
app_addr_t dest_address
Definition: wms_data.h:338
app_lib_data_to_send_t::num_bytes
size_t num_bytes
Definition: wms_data.h:336
node_configuration.h
App_Scheduler_addTask_execTime
app_scheduler_res_e App_Scheduler_addTask_execTime(task_cb_f cb, uint32_t delay_ms, uint32_t exec_time_us)
Add a task.
SPI_MODE_HIGH_FIRST
@ SPI_MODE_HIGH_FIRST
Definition: spi.h:22
spi_conf_t::mode
spi_mode_e mode
Definition: spi.h:37
SPI_RES_OK
@ SPI_RES_OK
Definition: spi.h:54
APP_LIB_DATA_NO_TRACKING_ID
#define APP_LIB_DATA_NO_TRACKING_ID
When sending data and no tracking of packet is requested, this ID may be used.
Definition: wms_data.h:60
APP_RES_OK
@ APP_RES_OK
Definition: wms_app.h:204
app_lib_state_route_info_t
Structure for route information.
Definition: wms_state.h:241
SPI_RES_ALREADY_INITIALIZED
@ SPI_RES_ALREADY_INITIALIZED
Definition: spi.h:58
spi_conf_t
Definition: spi.h:34
app_lib_state_route_info_t::state
app_lib_state_route_state_e state
Definition: wms_state.h:244
app_lib_data_to_send_t::dest_endpoint
uint8_t dest_endpoint
Definition: wms_data.h:354
spi_conf_t::bit_order
spi_bit_order_e bit_order
Definition: spi.h:38
app_scheduler.h
app_lib_data_to_send_t
A struct for lib_data->sendData().
Definition: wms_data.h:331
app_global_functions_t
List of global functions, passed to App_entrypoint()
Definition: wms_app.h:157
BOARD_SPI_LIS2DH12_CS_PIN
#define BOARD_SPI_LIS2DH12_CS_PIN
Definition: board.h:24
APP_LIB_DATA_QOS_HIGH
@ APP_LIB_DATA_QOS_HIGH
Definition: wms_data.h:91
SPI_init
spi_res_e SPI_init(spi_conf_t *conf_p)
Initialize SPI module.
configureNodeFromBuildParameters
__STATIC_INLINE app_res_e configureNodeFromBuildParameters()
Wrapper on top of configureNode to get parameters from build system and hardcoded values from chip (f...
Definition: node_configuration.h:233
spi_conf_t::clock
uint32_t clock
Definition: spi.h:36
App_Scheduler_cancelTask
app_scheduler_res_e App_Scheduler_cancelTask(task_cb_f cb)
Cancel a task.
spi_res_e
spi_res_e
Definition: spi.h:52
app_lib_data_to_send_t::flags
uint8_t flags
Definition: wms_data.h:350
APP_ADDR_ANYSINK
@ APP_ADDR_ANYSINK
Definition: wms_app.h:236
app_lib_data_to_send_t::qos
app_lib_data_qos_e qos
Definition: wms_data.h:348
app_lib_data_to_send_t::bytes
const uint8_t * bytes
Definition: wms_data.h:334
tlv.h
Library to encode/decode buffers in TLV (Type Length Value) format.
APP_SCHEDULER_SCHEDULE_ASAP
#define APP_SCHEDULER_SCHEDULE_ASAP
Value to return from task or as initial time to be executed ASAP.
Definition: app_scheduler.h:42
app_lib_data_to_send_t::delay
uint32_t delay
Definition: wms_data.h:342
APP_LIB_STATE_ROUTE_STATE_VALID
@ APP_LIB_STATE_ROUTE_STATE_VALID
Valid next hop / route.
Definition: wms_state.h:183
api.h