Implement the new button HAL: SmartRF06 + CC13xxEM/CC26xxEM

This commit is contained in:
George Oikonomou 2017-11-04 22:59:07 +00:00
parent 3014e8cf07
commit 3f4fef4625
6 changed files with 50 additions and 521 deletions

View File

@ -2,7 +2,7 @@ CFLAGS += -DBOARD_SMARTRF06EB=1
CONTIKI_TARGET_DIRS += srf06
BOARD_SOURCEFILES += srf06-sensors.c button-sensor.c board.c
BOARD_SOURCEFILES += srf06-sensors.c board-buttons.c board.c
BOARD_SOURCEFILES += als-sensor.c
### Signal that we can be programmed with cc2538-bsl

View File

@ -1,10 +1,11 @@
/*
* Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
@ -33,28 +34,30 @@
* @{
*
* \file
* Header file for the SmartRF06EB + CC13xx/CC26xxEM Button Driver
* Defines SmarfRF06 + CC13xxEM/CC26xxEM buttons for use with the button HAL
*/
/*---------------------------------------------------------------------------*/
#ifndef BUTTON_SENSOR_H_
#define BUTTON_SENSOR_H_
/*---------------------------------------------------------------------------*/
#include "lib/sensors.h"
/*---------------------------------------------------------------------------*/
#define BUTTON_SENSOR "Button"
/*---------------------------------------------------------------------------*/
#define BUTTON_SENSOR_VALUE_STATE 0
#define BUTTON_SENSOR_VALUE_DURATION 1
#include "contiki.h"
#include "dev/button-hal.h"
#define BUTTON_SENSOR_VALUE_RELEASED 0
#define BUTTON_SENSOR_VALUE_PRESSED 1
#include "ti-lib.h"
/*---------------------------------------------------------------------------*/
extern const struct sensors_sensor button_select_sensor;
extern const struct sensors_sensor button_left_sensor;
extern const struct sensors_sensor button_right_sensor;
extern const struct sensors_sensor button_up_sensor;
extern const struct sensors_sensor button_down_sensor;
BUTTON_HAL_BUTTON(key_left, "Key Left", BOARD_IOID_KEY_LEFT, \
GPIO_HAL_PIN_CFG_PULL_UP, BOARD_BUTTON_HAL_INDEX_KEY_LEFT, \
true);
BUTTON_HAL_BUTTON(key_right, "Key Right", BOARD_IOID_KEY_RIGHT, \
GPIO_HAL_PIN_CFG_PULL_UP, BOARD_BUTTON_HAL_INDEX_KEY_RIGHT, \
true);
BUTTON_HAL_BUTTON(key_up, "Key Up", BOARD_IOID_KEY_UP, \
GPIO_HAL_PIN_CFG_PULL_UP, BOARD_BUTTON_HAL_INDEX_KEY_UP, \
true);
BUTTON_HAL_BUTTON(key_down, "Key Down", BOARD_IOID_KEY_DOWN, \
GPIO_HAL_PIN_CFG_PULL_UP, BOARD_BUTTON_HAL_INDEX_KEY_DOWN, \
true);
BUTTON_HAL_BUTTON(key_select, "Key Select", BOARD_IOID_KEY_SELECT, \
GPIO_HAL_PIN_CFG_PULL_UP, \
BOARD_BUTTON_HAL_INDEX_KEY_SELECT, true);
/*---------------------------------------------------------------------------*/
#endif /* BUTTON_SENSOR_H_ */
BUTTON_HAL_BUTTONS(&key_left, &key_right, &key_up, &key_down, &key_select);
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -1,498 +0,0 @@
/*
* Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \addtogroup srf06-common-peripherals
* @{
*
* \file
* Driver for the SmartRF06EB buttons when a CC13xx/CC26xxEM is mounted on it
*/
/*---------------------------------------------------------------------------*/
#include "contiki.h"
#include "lib/sensors.h"
#include "srf06/button-sensor.h"
#include "gpio-hal.h"
#include "sys/timer.h"
#include "lpm.h"
#include "ti-lib.h"
#include <stdint.h>
/*---------------------------------------------------------------------------*/
#ifdef BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN
#define BUTTON_SENSOR_ENABLE_SHUTDOWN BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN
#else
#define BUTTON_SENSOR_ENABLE_SHUTDOWN 1
#endif
/*---------------------------------------------------------------------------*/
#define BUTTON_GPIO_CFG (IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | \
IOC_IOPULL_UP | IOC_SLEW_DISABLE | \
IOC_HYST_DISABLE | IOC_BOTH_EDGES | \
IOC_INT_ENABLE | IOC_IOMODE_NORMAL | \
IOC_NO_WAKE_UP | IOC_INPUT_ENABLE)
/*---------------------------------------------------------------------------*/
#define DEBOUNCE_DURATION (CLOCK_SECOND >> 5)
struct btn_timer {
struct timer debounce;
clock_time_t start;
clock_time_t duration;
};
static struct btn_timer sel_timer, left_timer, right_timer, up_timer,
down_timer;
/*---------------------------------------------------------------------------*/
/**
* \brief Handler for SmartRF button presses
*/
static void
button_press_handler(gpio_hal_pin_mask_t pin_mask)
{
if(pin_mask & gpio_hal_pin_to_mask(BOARD_IOID_KEY_SELECT)) {
if(!timer_expired(&sel_timer.debounce)) {
return;
}
timer_set(&sel_timer.debounce, DEBOUNCE_DURATION);
/*
* Start press duration counter on press (falling), notify on release
* (rising)
*/
if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_SELECT) == 0) {
sel_timer.start = clock_time();
sel_timer.duration = 0;
} else {
sel_timer.duration = clock_time() - sel_timer.start;
sensors_changed(&button_select_sensor);
}
}
if(pin_mask & gpio_hal_pin_to_mask(BOARD_IOID_KEY_LEFT)) {
if(!timer_expired(&left_timer.debounce)) {
return;
}
timer_set(&left_timer.debounce, DEBOUNCE_DURATION);
/*
* Start press duration counter on press (falling), notify on release
* (rising)
*/
if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_LEFT) == 0) {
left_timer.start = clock_time();
left_timer.duration = 0;
} else {
left_timer.duration = clock_time() - left_timer.start;
sensors_changed(&button_left_sensor);
}
}
if(pin_mask & gpio_hal_pin_to_mask(BOARD_IOID_KEY_RIGHT)) {
if(BUTTON_SENSOR_ENABLE_SHUTDOWN == 0) {
if(!timer_expired(&right_timer.debounce)) {
return;
}
timer_set(&right_timer.debounce, DEBOUNCE_DURATION);
/*
* Start press duration counter on press (falling), notify on release
* (rising)
*/
if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_RIGHT) == 0) {
right_timer.start = clock_time();
right_timer.duration = 0;
} else {
right_timer.duration = clock_time() - right_timer.start;
sensors_changed(&button_right_sensor);
}
} else {
lpm_shutdown(BOARD_IOID_KEY_RIGHT, IOC_IOPULL_UP, IOC_WAKE_ON_LOW);
}
}
if(pin_mask & gpio_hal_pin_to_mask(BOARD_IOID_KEY_UP)) {
if(!timer_expired(&up_timer.debounce)) {
return;
}
timer_set(&up_timer.debounce, DEBOUNCE_DURATION);
/*
* Start press duration counter on press (falling), notify on release
* (rising)
*/
if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_UP) == 0) {
up_timer.start = clock_time();
up_timer.duration = 0;
} else {
up_timer.duration = clock_time() - up_timer.start;
sensors_changed(&button_up_sensor);
}
}
if(pin_mask & gpio_hal_pin_to_mask(BOARD_IOID_KEY_DOWN)) {
if(!timer_expired(&down_timer.debounce)) {
return;
}
timer_set(&down_timer.debounce, DEBOUNCE_DURATION);
/*
* Start press duration counter on press (falling), notify on release
* (rising)
*/
if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_DOWN) == 0) {
down_timer.start = clock_time();
down_timer.duration = 0;
} else {
down_timer.duration = clock_time() - down_timer.start;
sensors_changed(&button_down_sensor);
}
}
}
/*---------------------------------------------------------------------------*/
static gpio_hal_event_handler_t press_handler = {
.next = NULL,
.handler = button_press_handler,
.pin_mask = 0,
};
/*---------------------------------------------------------------------------*/
/**
* \brief Configuration function for the button sensor for all buttons.
*
* \param type This function does nothing unless type == SENSORS_ACTIVE
* \param c 0: disable the button, non-zero: enable
* \param key: One of BOARD_KEY_LEFT, BOARD_KEY_RIGHT etc
*/
static void
config_buttons(int type, int c, uint32_t key)
{
switch(type) {
case SENSORS_HW_INIT:
ti_lib_gpio_clear_event_dio(key);
ti_lib_rom_ioc_pin_type_gpio_input(key);
ti_lib_rom_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG);
press_handler.pin_mask |= gpio_hal_pin_to_mask(key);
gpio_hal_register_handler(&press_handler);
break;
case SENSORS_ACTIVE:
if(c) {
ti_lib_gpio_clear_event_dio(key);
ti_lib_rom_ioc_pin_type_gpio_input(key);
ti_lib_rom_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG);
ti_lib_rom_ioc_int_enable(key);
} else {
ti_lib_rom_ioc_int_disable(key);
}
break;
default:
break;
}
}
/*---------------------------------------------------------------------------*/
/**
* \brief Configuration function for the select button.
*
* Parameters are passed onto config_buttons, which does the actual
* configuration
* Parameters are ignored. They have been included because the prototype is
* dictated by the core sensor api. The return value is also required by
* the API but otherwise ignored.
*
* \param type passed to config_buttons as-is
* \param value passed to config_buttons as-is
*
* \return ignored
*/
static int
config_select(int type, int value)
{
config_buttons(type, value, BOARD_IOID_KEY_SELECT);
return 1;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Configuration function for the left button.
*
* Parameters are passed onto config_buttons, which does the actual
* configuration
* Parameters are ignored. They have been included because the prototype is
* dictated by the core sensor api. The return value is also required by
* the API but otherwise ignored.
*
* \param type passed to config_buttons as-is
* \param value passed to config_buttons as-is
*
* \return ignored
*/
static int
config_left(int type, int value)
{
config_buttons(type, value, BOARD_IOID_KEY_LEFT);
return 1;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Configuration function for the right button.
*
* Parameters are passed onto config_buttons, which does the actual
* configuration
* Parameters are ignored. They have been included because the prototype is
* dictated by the core sensor api. The return value is also required by
* the API but otherwise ignored.
*
* \param type passed to config_buttons as-is
* \param value passed to config_buttons as-is
*
* \return ignored
*/
static int
config_right(int type, int value)
{
config_buttons(type, value, BOARD_IOID_KEY_RIGHT);
return 1;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Configuration function for the up button.
*
* Parameters are passed onto config_buttons, which does the actual
* configuration
* Parameters are ignored. They have been included because the prototype is
* dictated by the core sensor api. The return value is also required by
* the API but otherwise ignored.
*
* \param type passed to config_buttons as-is
* \param value passed to config_buttons as-is
*
* \return ignored
*/
static int
config_up(int type, int value)
{
config_buttons(type, value, BOARD_IOID_KEY_UP);
return 1;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Configuration function for the down button.
*
* Parameters are passed onto config_buttons, which does the actual
* configuration
* Parameters are ignored. They have been included because the prototype is
* dictated by the core sensor api. The return value is also required by
* the API but otherwise ignored.
*
* \param type passed to config_buttons as-is
* \param value passed to config_buttons as-is
*
* \return ignored
*/
static int
config_down(int type, int value)
{
config_buttons(type, value, BOARD_IOID_KEY_DOWN);
return 1;
}
/*---------------------------------------------------------------------------*/
static int
value_select(int type)
{
if(type == BUTTON_SENSOR_VALUE_STATE) {
return ti_lib_gpio_read_dio(BOARD_IOID_KEY_SELECT) == 0 ?
BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED;
} else if(type == BUTTON_SENSOR_VALUE_DURATION) {
return (int)sel_timer.duration;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static int
value_left(int type)
{
if(type == BUTTON_SENSOR_VALUE_STATE) {
return ti_lib_gpio_read_dio(BOARD_IOID_KEY_LEFT) == 0 ?
BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED;
} else if(type == BUTTON_SENSOR_VALUE_DURATION) {
return (int)left_timer.duration;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static int
value_right(int type)
{
if(type == BUTTON_SENSOR_VALUE_STATE) {
return ti_lib_gpio_read_dio(BOARD_IOID_KEY_RIGHT) == 0 ?
BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED;
} else if(type == BUTTON_SENSOR_VALUE_DURATION) {
return (int)right_timer.duration;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static int
value_up(int type)
{
if(type == BUTTON_SENSOR_VALUE_STATE) {
return ti_lib_gpio_read_dio(BOARD_IOID_KEY_UP) == 0 ?
BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED;
} else if(type == BUTTON_SENSOR_VALUE_DURATION) {
return (int)up_timer.duration;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static int
value_down(int type)
{
if(type == BUTTON_SENSOR_VALUE_STATE) {
return ti_lib_gpio_read_dio(BOARD_IOID_KEY_DOWN) == 0 ?
BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED;
} else if(type == BUTTON_SENSOR_VALUE_DURATION) {
return (int)down_timer.duration;
}
return 0;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Status function for all buttons
* \param type SENSORS_ACTIVE or SENSORS_READY
* \param key_io_id BOARD_IOID_KEY_LEFT, BOARD_IOID_KEY_RIGHT etc
* \return 1 if the button's port interrupt is enabled (edge detect)
*
* This function will only be called by status_left, status_right and the
* called will pass the correct key_io_id
*/
static int
status(int type, uint32_t key_io_id)
{
switch(type) {
case SENSORS_ACTIVE:
case SENSORS_READY:
if(ti_lib_ioc_port_configure_get(key_io_id) & IOC_INT_ENABLE) {
return 1;
}
break;
default:
break;
}
return 0;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Status function for the select button.
* \param type SENSORS_ACTIVE or SENSORS_READY
* \return 1 if the button's port interrupt is enabled (edge detect)
*
* This function will call status. It will pass type verbatim and it will also
* pass the correct key_io_id
*/
static int
status_select(int type)
{
return status(type, BOARD_IOID_KEY_SELECT);
}
/*---------------------------------------------------------------------------*/
/**
* \brief Status function for the left button.
* \param type SENSORS_ACTIVE or SENSORS_READY
* \return 1 if the button's port interrupt is enabled (edge detect)
*
* This function will call status. It will pass type verbatim and it will also
* pass the correct key_io_id
*/
static int
status_left(int type)
{
return status(type, BOARD_IOID_KEY_LEFT);
}
/*---------------------------------------------------------------------------*/
/**
* \brief Status function for the right button.
* \param type SENSORS_ACTIVE or SENSORS_READY
* \return 1 if the button's port interrupt is enabled (edge detect)
*
* This function will call status. It will pass type verbatim and it will also
* pass the correct key_io_id
*/
static int
status_right(int type)
{
return status(type, BOARD_IOID_KEY_RIGHT);
}
/*---------------------------------------------------------------------------*/
/**
* \brief Status function for the up button.
* \param type SENSORS_ACTIVE or SENSORS_READY
* \return 1 if the button's port interrupt is enabled (edge detect)
*
* This function will call status. It will pass type verbatim and it will also
* pass the correct key_io_id
*/
static int
status_up(int type)
{
return status(type, BOARD_IOID_KEY_UP);
}
/*---------------------------------------------------------------------------*/
/**
* \brief Status function for the down button.
* \param type SENSORS_ACTIVE or SENSORS_READY
* \return 1 if the button's port interrupt is enabled (edge detect)
*
* This function will call status. It will pass type verbatim and it will also
* pass the correct key_io_id
*/
static int
status_down(int type)
{
return status(type, BOARD_IOID_KEY_DOWN);
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(button_select_sensor, BUTTON_SENSOR, value_select,
config_select, status_select);
SENSORS_SENSOR(button_left_sensor, BUTTON_SENSOR, value_left, config_left,
status_left);
SENSORS_SENSOR(button_right_sensor, BUTTON_SENSOR, value_right, config_right,
status_right);
SENSORS_SENSOR(button_up_sensor, BUTTON_SENSOR, value_up, config_up, status_up);
SENSORS_SENSOR(button_down_sensor, BUTTON_SENSOR, value_down, config_down,
status_down);
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -232,6 +232,19 @@
#endif
/** @} */
/*---------------------------------------------------------------------------*/
/**
* \brief Board indices for the button HAL
*
* Those values are not meant to be modified by the user
* @{
*/
#define BOARD_BUTTON_HAL_INDEX_KEY_LEFT 0x00
#define BOARD_BUTTON_HAL_INDEX_KEY_RIGHT 0x01
#define BOARD_BUTTON_HAL_INDEX_KEY_UP 0x02
#define BOARD_BUTTON_HAL_INDEX_KEY_DOWN 0x03
#define BOARD_BUTTON_HAL_INDEX_KEY_SELECT 0x04
/** @} */
/*---------------------------------------------------------------------------*/
/**
* \name Device string used on startup
* @{

View File

@ -232,6 +232,19 @@
#endif
/** @} */
/*---------------------------------------------------------------------------*/
/**
* \brief Board indices for the button HAL
*
* Those values are not meant to be modified by the user
* @{
*/
#define BOARD_BUTTON_HAL_INDEX_KEY_LEFT 0x00
#define BOARD_BUTTON_HAL_INDEX_KEY_RIGHT 0x01
#define BOARD_BUTTON_HAL_INDEX_KEY_UP 0x02
#define BOARD_BUTTON_HAL_INDEX_KEY_DOWN 0x03
#define BOARD_BUTTON_HAL_INDEX_KEY_SELECT 0x04
/** @} */
/*---------------------------------------------------------------------------*/
/**
* \name Device string used on startup
* @{

View File

@ -38,13 +38,11 @@
*/
/*---------------------------------------------------------------------------*/
#include "contiki.h"
#include "srf06/button-sensor.h"
#include "srf06/als-sensor.h"
#include <string.h>
/*---------------------------------------------------------------------------*/
/** \brief Exports a global symbol to be used by the sensor API */
SENSORS(&button_select_sensor, &button_left_sensor, &button_right_sensor,
&button_up_sensor, &button_down_sensor, &als_sensor);
SENSORS(&als_sensor);
/*---------------------------------------------------------------------------*/
/** @} */