1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers/srf04: initial driver implementation

This commit is contained in:
Semjon Kerner 2018-09-20 13:00:57 +02:00
parent c7e6d15990
commit b24de4a22a
6 changed files with 278 additions and 0 deletions

View File

@ -405,6 +405,12 @@ ifneq (,$(filter srf02,$(USEMODULE)))
USEMODULE += xtimer
endif
ifneq (,$(filter srf04,$(USEMODULE)))
USEMODULE += xtimer
FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_gpio_irq
endif
ifneq (,$(filter srf08,$(USEMODULE)))
FEATURES_REQUIRED += periph_i2c
USEMODULE += xtimer

View File

@ -222,6 +222,10 @@ ifneq (,$(filter soft_spi,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/soft_spi/include
endif
ifneq (,$(filter srf04,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/srf04/include
endif
ifneq (,$(filter sx127x,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/sx127x/include
endif

110
drivers/include/srf04.h Normal file
View File

@ -0,0 +1,110 @@
/*
* Copyright (C) 2018 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup drivers_srf04 srf04 ultra sonic range finder
* @ingroup drivers_sensors
* @brief Device driver for the srf04 ultra sonic range finder
* @{
*
* @file
* @brief Device driver for the srf04 ultra sonic range finder
*
* @author Semjon Kerner <semjon.kerner@fu-berlin.de>
*/
#ifndef SRF04_H
#define SRF04_H
#include <stdint.h>
#include <stdio.h>
#include "periph/gpio.h"
#include "xtimer.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Status and error return codes
*/
enum {
SRF04_OK = 0, /**< exit without error */
SRF04_ERR_INVALID = -1, /**< error no valid measurement available*/
SRF04_ERR_MEASURING = -2, /**< error sensor is measuring*/
SRF04_ERR_GPIO = -3, /**< error initializing gpio*/
};
/**
* @brief GPIO pins for srf04 device
*/
typedef struct {
gpio_t trigger; /**< GPIO Port the trigger pin is connected to */
gpio_t echo; /**< GPIO Port the echo pin is connected to */
} srf04_params_t;
/**
* @brief Device descriptor for srf04 sensor
*/
typedef struct {
srf04_params_t p; /**< GPIO Ports of device */
int distance; /**< raw time of flight distance */
uint32_t time; /**< timestamp of trigger or echo */
} srf04_t;
/**
* @brief Initialize gpio and interrupt
*
* @param[out] dev device descriptor of sensor to initialize
* @param[in] params init param struct holding gpio trigger and echo pins
*
* @return SRF04_OK on success
* @return SRF04_GPIO on gpio init failure
*/
int srf04_init(srf04_t *dev, const srf04_params_t *params);
/**
* @brief Triggers measurement
*
* @param[in] dev device descriptor of sensor
*/
void srf04_trigger(const srf04_t *dev);
/**
* @brief Returns time of flight in ms
*
* @note should not be invoked within 50 ms after triggering
*
* @param[in] dev device descriptor of sensor
*
* @return time of flight in ms
* @return SRF04_MEASURING if measurement is in progress
* @return SRF04_INVALID if no valid measurement is available
*/
int srf04_read(const srf04_t* dev);
/**
* @brief Convenience function triggers a measurement and returns distance
*
* @note This function will return after 50 ms once new data is available
*
* @param[in] dev device descriptor of sensor
*
* @return time of flight in mm
* @return SRF04_MEASURING if measurement is in progress
* @return SRF04_INVALID if no valid measurement is available
*/
int srf04_get_distance(const srf04_t* dev);
#ifdef __cplusplus
}
#endif
#endif /* SRF04_H */
/** @} */

1
drivers/srf04/Makefile Normal file
View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2018 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_srf04
*
* @{
* @file
* @brief Default configuration for srf04 devices
*
* @author Semjon Kerner <semjon.kerner@fu-berlin.de>
*/
#ifndef SRF04_PARAMS_H
#define SRF04_PARAMS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "board.h"
#include "srf04.h"
/**
* @name Default configuration parameters for SRF04 device
* @{
*/
#ifndef SRF04_PARAM_TRIGGER
#define SRF04_PARAM_TRIGGER GPIO_PIN(0,13)
#endif
#ifndef SRF04_PARAM_ECHO
#define SRF04_PARAM_ECHO GPIO_PIN(0,14)
#endif
#ifndef SRF04_PARAMS
#define SRF04_PARAMS \
{ .trigger = SRF04_PARAM_TRIGGER, \
.echo = SRF04_PARAM_ECHO, \
}
#endif
/** @} */
/**
* @brief SRF04 configuration
*/
static const srf04_params_t srf04_params[] = {
SRF04_PARAMS
};
#define SRF04_NUMOF (sizeof(srf04_params) / sizeof(srf04_params[0]))
#ifdef __cplusplus
}
#endif
#endif /* SRF04_PARAMS_H */
/** @} */

95
drivers/srf04/srf04.c Normal file
View File

@ -0,0 +1,95 @@
/*
* Copyright (C) 2018 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_srf04
* @{
*
* @file
* @brief driver for srf04 ultra sonic range finder
*
* @author Semjon Kerner <semjon.kerner@fu-berlin.de>
*
* @}
*/
#include "srf04.h"
#include "srf04_params.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#define SRF04_DISTANCE (584U)
#define SRF04_SAMPLE_PERIOD (50U * US_PER_MS)
static void _cb(void *arg)
{
uint32_t t = xtimer_now_usec();
srf04_t* dev = (srf04_t*)arg;
if (dev->distance > SRF04_ERR_MEASURING) {
dev->distance = SRF04_ERR_MEASURING;
dev->time = t;
} else {
gpio_irq_disable(dev->p.echo);
dev->distance = (t - dev->time);
}
}
int srf04_init(srf04_t* dev, const srf04_params_t *params)
{
dev->p = *params;
dev->distance = SRF04_ERR_INVALID;
dev->time = 0;
if (gpio_init(dev->p.trigger, GPIO_OUT) != 0) {
DEBUG("[srf04] Error: could not initialize GPIO trigger pin\n");
return SRF04_ERR_GPIO;
}
if (gpio_init_int(dev->p.echo, GPIO_IN, GPIO_BOTH, _cb, (void*)dev) != 0) {
DEBUG("[srf04] Error: could not initialize GPIO echo pin\n");
return SRF04_ERR_GPIO;
}
gpio_irq_disable(dev->p.echo);
return SRF04_OK;
}
void srf04_trigger(const srf04_t* dev)
{
if (dev->distance == SRF04_ERR_MEASURING) {
return;
}
gpio_irq_enable(dev->p.echo);
gpio_set(dev->p.trigger);
xtimer_usleep(10);
gpio_clear(dev->p.trigger);
}
int srf04_read(const srf04_t* dev)
{
return dev->distance;
}
int srf04_get_distance(const srf04_t* dev)
{
/* trigger new reading */
srf04_trigger(dev);
/* give the sensor the required time for sampling */
xtimer_usleep(SRF04_SAMPLE_PERIOD);
/* get the result */
if (dev->distance >= SRF04_OK) {
return ((dev->distance * 100) / SRF04_DISTANCE);
}
return dev->distance;
}