blob: d8568d31469c5d8c8d788b8ea0ae60f1fcc4f2c7 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* resarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "os/mynewt.h"
#include "sensor/sensor.h"
#include "sensor/mag.h"
#include "sim/sim_mag.h"
/* Exports for the sensor interface.
*/
static int sim_mag_sensor_read(struct sensor *, sensor_type_t,
sensor_data_func_t, void *, uint32_t);
static int sim_mag_sensor_get_config(struct sensor *, sensor_type_t,
struct sensor_cfg *);
static const struct sensor_driver g_sim_mag_sensor_driver = {
sim_mag_sensor_read,
sim_mag_sensor_get_config
};
/**
* Expects to be called back through os_dev_create().
*
* @param The device object associated with this magnetometer
* @param Argument passed to OS device init, unused
*
* @return 0 on success, non-zero error on failure.
*/
int
sim_mag_init(struct os_dev *dev, void *arg)
{
struct sim_mag *sm;
struct sensor *sensor;
int rc;
sm = (struct sim_mag *) dev;
sensor = &sm->sm_sensor;
rc = sensor_init(sensor, dev);
if (rc != 0) {
goto err;
}
rc = sensor_set_driver(sensor, SENSOR_TYPE_MAGNETIC_FIELD,
(struct sensor_driver *) &g_sim_mag_sensor_driver);
if (rc != 0) {
goto err;
}
rc = sensor_mgr_register(sensor);
if (rc != 0) {
goto err;
}
return (0);
err:
return (rc);
}
int
sim_mag_config(struct sim_mag *sm, struct sim_mag_cfg *cfg)
{
/* Overwrite the configuration associated with this generic magnetometer. */
memcpy(&sm->sm_cfg, cfg, sizeof(*cfg));
return (0);
}
static int
sim_mag_sensor_read(struct sensor *sensor, sensor_type_t type,
sensor_data_func_t data_func, void *data_arg, uint32_t timeout)
{
struct sim_mag *sm;
struct sensor_mag_data smd;
os_time_t now;
uint32_t num_samples;
int i;
int rc;
/* If the read isn't looking for mag data, then don't do anything. */
if (!(type & SENSOR_TYPE_MAGNETIC_FIELD)) {
rc = SYS_EINVAL;
goto err;
}
sm = (struct sim_mag *) SENSOR_GET_DEVICE(sensor);
/* When a sensor is "read", we get the last 'n' samples from the device
* and pass them to the sensor data function. Based on the sample
* interval provided to sim_mag_config() and the last time this function
* was called, 'n' samples are generated.
*/
now = os_time_get();
num_samples = (now - sm->sm_last_read_time) / sm->sm_cfg.smc_sample_itvl;
num_samples = min(num_samples, sm->sm_cfg.smc_nr_samples);
/* By default only readings are provided for 1-axis (x), however,
* if number of axises is configured, up to 3-axises of data can be
* returned.
*/
smd.smd_x = 0.0;
smd.smd_y = 0.0;
smd.smd_z = 0.0;
smd.smd_x_is_valid = 1;
smd.smd_y_is_valid = 0;
smd.smd_z_is_valid = 0;
if (sm->sm_cfg.smc_nr_axises > 1) {
smd.smd_y = 0.0;
}
if (sm->sm_cfg.smc_nr_axises > 2) {
smd.smd_z = 0.0;
}
/* Call data function for each of the generated readings. */
for (i = 0; i < num_samples; i++) {
rc = data_func(sensor, data_arg, &smd, SENSOR_TYPE_MAGNETIC_FIELD);
if (rc != 0) {
goto err;
}
}
return (0);
err:
return (rc);
}
static int
sim_mag_sensor_get_config(struct sensor *sensor, sensor_type_t type,
struct sensor_cfg *cfg)
{
int rc;
if (type != SENSOR_TYPE_MAGNETIC_FIELD) {
rc = SYS_EINVAL;
goto err;
}
cfg->sc_valtype = SENSOR_VALUE_TYPE_FLOAT_TRIPLET;
return (0);
err:
return (rc);
}