Initial commit of firmware
This commit is contained in:
191
Libs/platform/driver/button/inc/sl_button.h
Normal file
191
Libs/platform/driver/button/inc/sl_button.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Button Driver
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_BUTTON_H
|
||||
#define SL_BUTTON_H
|
||||
|
||||
#include "sl_common.h"
|
||||
#include "sl_status.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup button Button API
|
||||
* @brief Generic Button API
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** DEFINES ************************************
|
||||
******************************************************************************/
|
||||
|
||||
#define BUTTON_ERROR 0xFFFF ///< Error when trying to return state
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** DATA TYPES *********************************
|
||||
******************************************************************************/
|
||||
|
||||
typedef uint8_t sl_button_mode_t; ///< BUTTON mode
|
||||
typedef uint8_t sl_button_state_t; ///< BUTTON state
|
||||
typedef struct sl_button sl_button_t; ///< BUTTON Instance structure
|
||||
|
||||
/// A BUTTON instance
|
||||
typedef struct sl_button {
|
||||
void *context; ///< The context for this BUTTON instance
|
||||
sl_status_t (*init)(const sl_button_t *handle); ///< Member function to initialize BUTTON instance
|
||||
void (*poll)(const sl_button_t *handle); ///< Member function to poll BUTTON
|
||||
void (*enable)(const sl_button_t *handle); ///< Member function to enable BUTTON
|
||||
void (*disable)(const sl_button_t *handle); ///< Member function to disable BUTTON
|
||||
sl_button_state_t (*get_state)(const sl_button_t *handle); ///< Member function to retrieve BUTTON state
|
||||
} sl_button;
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* Button driver init. This function should be called before calling any other
|
||||
* button function. Sets up the GPIO. Sets the mode of operation. Sets up the
|
||||
* interrupts based on the mode of operation.
|
||||
*
|
||||
* @param[in] handle Pointer to button instance
|
||||
*
|
||||
* @return Status Code:
|
||||
* - SL_STATUS_OK
|
||||
******************************************************************************/
|
||||
sl_status_t sl_button_init(const sl_button_t *handle);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get button state.
|
||||
*
|
||||
* @param[in] handle Pointer to button instance
|
||||
*
|
||||
* @return Button state Current state of the button
|
||||
******************************************************************************/
|
||||
sl_button_state_t sl_button_get_state(const sl_button_t *handle);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enable the button.
|
||||
*
|
||||
* @param[in] handle Pointer to button instance
|
||||
*
|
||||
******************************************************************************/
|
||||
void sl_button_enable(const sl_button_t *handle);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Disable the button.
|
||||
*
|
||||
* @param[in] handle Pointer to button instance
|
||||
*
|
||||
******************************************************************************/
|
||||
void sl_button_disable(const sl_button_t *handle);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Poll the button.
|
||||
*
|
||||
* @param[in] handle Pointer to button instance
|
||||
******************************************************************************/
|
||||
void sl_button_poll_step(const sl_button_t *handle);
|
||||
|
||||
/***************************************************************************//**
|
||||
* A callback called in interrupt context whenever a button changes its state.
|
||||
*
|
||||
* @remark Can be implemented by the application if required. This function
|
||||
* can contain the functionality to be executed in response to changes of state
|
||||
* in each of the buttons, or callbacks to appropriate functionality.
|
||||
*
|
||||
* @note The button state should not be updated in this function, it is updated
|
||||
* by specific button driver prior to arriving here
|
||||
*
|
||||
@param[out] handle Pointer to button instance
|
||||
******************************************************************************/
|
||||
void sl_button_on_change(const sl_button_t *handle);
|
||||
|
||||
/** @} (end addtogroup button) */
|
||||
|
||||
// ******** THE REST OF THE FILE IS DOCUMENTATION ONLY !***********************
|
||||
/// @addtogroup button Button API
|
||||
/// @{
|
||||
///
|
||||
/// @details
|
||||
///
|
||||
/// @n @section buttondrv_intro Introduction
|
||||
///
|
||||
/// The button driver is a platfom level software module that manages the initialization
|
||||
/// and reading of various types of buttons. There is currently one type of button
|
||||
/// supported by the button driver:
|
||||
///
|
||||
/// @li @ref simple_button
|
||||
///
|
||||
/// All button functions are called through the generic driver, which then references
|
||||
/// functions in the simple button and other potential future button drivers.
|
||||
///
|
||||
/// @n @section buttondrv_config Configuration
|
||||
///
|
||||
/// All button instances are configured with an @ref sl_button_t struct and a type specific
|
||||
/// context struct. These structs are automatically generated after a button is set up
|
||||
/// using Simplicity Studio's wizard, along with a function definition for initializing all
|
||||
/// LEDs of that type. Specific setup for the simple button is in the following section.
|
||||
///
|
||||
/// - [Simple Button Configuration](/gecko-platform/<docspace-docleaf-version>/platform-driver/simple-button#simple-button-configuration)
|
||||
///
|
||||
/// @n @section buttondrv_usage Usage
|
||||
///
|
||||
/// Once the button structs are defined, the common button functions can be called being
|
||||
/// passed an instance of sl_button_t, which will be redirected to calling the type specific
|
||||
/// version of that function. The common functions include the following:
|
||||
///
|
||||
/// @li @ref sl_button_init
|
||||
/// @li @ref sl_button_get_state
|
||||
/// @li @ref sl_button_poll_step
|
||||
/// @li @ref sl_button_on_change
|
||||
///
|
||||
/// @ref sl_button_init must be called before attempting to read the state of the button.
|
||||
///
|
||||
/// The button driver can either be used with interrupt mode, polling or polling with debounce.
|
||||
/// In the case of using interrupt mode, @ref sl_button_on_change can be implemented by the
|
||||
/// application if required. This function can contain functionality to be executed in response
|
||||
/// to button event or callbacks to appropriate functionality.
|
||||
/// In the case of polling and polling with debounce mode, @ref sl_button_poll_step is used to
|
||||
/// update the state, and needs to be called from a tick function or similar by the user.
|
||||
/// These mode can be configured per button instance in the instance specific config file.
|
||||
///
|
||||
/// Both the interrupt and polling methods obtain the button state for the user by calling
|
||||
/// @ref sl_button_get_state.
|
||||
///
|
||||
/// @} end group button ********************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_BUTTON_H
|
||||
225
Libs/platform/driver/button/inc/sl_simple_button.h
Normal file
225
Libs/platform/driver/button/inc/sl_simple_button.h
Normal file
@@ -0,0 +1,225 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Simple Button Driver
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_SIMPLE_BUTTON_H
|
||||
#define SL_SIMPLE_BUTTON_H
|
||||
|
||||
#include "sl_button.h"
|
||||
#include "sl_gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup button
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup simple_button Simple Button Driver
|
||||
* @details Simple Button Driver module provides APIs to initalize and read
|
||||
* simple buttons. Subsequent sections provide more insight into button
|
||||
* driver configuration and usage.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** DEFINES ************************************
|
||||
******************************************************************************/
|
||||
|
||||
#define SL_SIMPLE_BUTTON_MODE_POLL 0U ///< BUTTON input capture using polling
|
||||
#define SL_SIMPLE_BUTTON_MODE_POLL_AND_DEBOUNCE 1U ///< BUTTON input capture using polling and debouncing
|
||||
#define SL_SIMPLE_BUTTON_MODE_INTERRUPT 2U ///< BUTTON input capture using interrupt
|
||||
|
||||
#define SL_SIMPLE_BUTTON_DISABLED 2U ///< BUTTON state is disabled
|
||||
#define SL_SIMPLE_BUTTON_PRESSED 1U ///< BUTTON state is pressed
|
||||
#define SL_SIMPLE_BUTTON_RELEASED 0U ///< BUTTON state is released
|
||||
|
||||
#define SL_SIMPLE_BUTTON_GET_STATE(context) (((sl_simple_button_context_t *)(context))->state) ///< BUTTON member function to get state
|
||||
#define SL_SIMPLE_BUTTON_GET_PORT(context) (((sl_simple_button_context_t *)(context))->port) ///< BUTTON member function to get port
|
||||
#define SL_SIMPLE_BUTTON_GET_PIN(context) (((sl_simple_button_context_t *)(context))->pin) ///< BUTTON member function to get pin
|
||||
#define SL_SIMPLE_BUTTON_GET_MODE(context) (((sl_simple_button_context_t *)(context))->mode) ///< BUTTON member function to get mode
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** DATA TYPES *********************************
|
||||
******************************************************************************/
|
||||
|
||||
/// A Simple BUTTON instance
|
||||
typedef struct {
|
||||
sl_button_state_t state; ///< Current button state
|
||||
uint16_t history; ///< History of button states
|
||||
sl_gpio_port_t port; ///< Button port
|
||||
uint8_t pin; ///< Button pin
|
||||
sl_button_mode_t mode; ///< Mode of operation
|
||||
} sl_simple_button_context_t;
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize the simple button driver.
|
||||
*
|
||||
* @param[in] handle Pointer to button handle:
|
||||
* - sl_button_t
|
||||
*
|
||||
* @return Status Code:
|
||||
* - SL_STATUS_OK
|
||||
******************************************************************************/
|
||||
sl_status_t sl_simple_button_init(const sl_button_t *handle);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get the current state of the simple button.
|
||||
*
|
||||
* @param[in] handle Pointer to button handle:
|
||||
* - sl_button_t
|
||||
*
|
||||
* @return Button State: Current state of the button
|
||||
* - SL_SIMPLE_BUTTON_PRESSED
|
||||
* - SL_SIMPLE_BUTTON_RELEASED
|
||||
******************************************************************************/
|
||||
sl_button_state_t sl_simple_button_get_state(const sl_button_t *handle);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Poll the simple button. (button mode - poll / poll and debonuce)
|
||||
*
|
||||
* @param[in] handle Pointer to button handle:
|
||||
* - sl_button_t
|
||||
******************************************************************************/
|
||||
void sl_simple_button_poll_step(const sl_button_t *handle);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enable the simple button.
|
||||
*
|
||||
* @param[in] handle Pointer to button handle:
|
||||
* - sl_button_t
|
||||
******************************************************************************/
|
||||
void sl_simple_button_enable(const sl_button_t *handle);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Disable the simple button.
|
||||
*
|
||||
* @param[in] handle Pointer to button handle:
|
||||
* - sl_button_t
|
||||
******************************************************************************/
|
||||
void sl_simple_button_disable(const sl_button_t *handle);
|
||||
|
||||
/** @} (end addtogroup simple_button) */
|
||||
/** @} (end addtogroup button) */
|
||||
|
||||
// ******** THE REST OF THE FILE IS DOCUMENTATION ONLY !***********************
|
||||
/// @addtogroup simple_button Simple Button Driver
|
||||
/// @{
|
||||
///
|
||||
/// @details
|
||||
///
|
||||
///
|
||||
/// @n @section simple_button_intro Introduction
|
||||
///
|
||||
/// The Simple Button driver is a module of the button driver that provides the functionality
|
||||
/// to initialize and read simple buttons.
|
||||
///
|
||||
/// @n @section simple_button_config Simple Button Configuration
|
||||
///
|
||||
/// Simple buttons use the @ref sl_button_t struct and their @ref sl_simple_button_context_t
|
||||
/// struct. These are automatically generated into the following files, as well as
|
||||
/// instance specific headers with macro definitions in them. The samples below
|
||||
/// are for a single instance called "inst0".
|
||||
///
|
||||
/// @code{.c}
|
||||
///// sl_simple_button_instances.c
|
||||
///
|
||||
///#include "sl_simple_button.h"
|
||||
///#include "sl_simple_button_inst0_config.h"
|
||||
///
|
||||
///sl_simple_button_context_t simple_inst0_context = {
|
||||
/// .state = 0,
|
||||
/// .history = 0,
|
||||
/// .port = SL_SIMPLE_BUTTON_INST0_PORT,
|
||||
/// .pin = SL_SIMPLE_BUTTON_INST0_PIN,
|
||||
/// .mode = SL_SIMPLE_BUTTON_INST0_MODE,
|
||||
///};
|
||||
///
|
||||
///const sl_button_t sl_button_inst0 = {
|
||||
/// .context = &simple_inst0_context,
|
||||
/// .init = sl_simple_button_init,
|
||||
/// .get_state = sl_simple_button_get_state,
|
||||
/// .poll = sl_simple_button_poll_step,
|
||||
///};
|
||||
///
|
||||
///const sl_button_t *sl_simple_button_array[] = {&sl_button_inst0};
|
||||
///const uint8_t simple_button_count = 1;
|
||||
///
|
||||
///void sl_simple_button_init_instances(void)
|
||||
///{
|
||||
/// sl_button_init(&sl_button_inst0);
|
||||
///}
|
||||
///
|
||||
///void sl_simple_button_poll_instances(void)
|
||||
///{
|
||||
/// sl_button_poll_step(&sl_button_inst0);
|
||||
///}
|
||||
/// @endcode
|
||||
///
|
||||
/// @note The sl_simple_button_instances.c file is shown with only one instance, but if more
|
||||
/// were in use they would all appear in this .c file.
|
||||
///
|
||||
/// @code{.c}
|
||||
///// sl_simple_button_instances.h
|
||||
///
|
||||
///#ifndef SL_SIMPLE_BUTTON_INSTANCES_H
|
||||
///#define SL_SIMPLE_BUTTON_INSTANCES_H
|
||||
///
|
||||
///#include "sl_simple_button.h"
|
||||
///
|
||||
///extern const sl_button_t sl_button_inst0;
|
||||
///
|
||||
///void sl_simple_button_init_instances(void);
|
||||
///void sl_simple_button_poll_instances(void);
|
||||
///
|
||||
///#endif // SL_SIMPLE_BUTTON_INSTANCES_H
|
||||
/// @endcode
|
||||
///
|
||||
/// @note The sl_simple_button_instances.h file is shown with only one instance, but if more
|
||||
/// were in use they would all appear in this .h file.
|
||||
///
|
||||
/// @n @section simple_button_usage Simple Button Usage
|
||||
///
|
||||
/// The simple button driver has no differences in its usage from the common button driver.
|
||||
/// See @ref buttondrv_usage.
|
||||
///
|
||||
/// @} end group simple_button ********************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_SIMPLE_BUTTON_H
|
||||
76
Libs/platform/driver/button/src/sl_button.c
Normal file
76
Libs/platform/driver/button/src/sl_button.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Button Driver
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_button.h"
|
||||
#include <stddef.h>
|
||||
|
||||
sl_status_t sl_button_init(const sl_button_t *handle)
|
||||
{
|
||||
if (handle->init != NULL) {
|
||||
return handle->init(handle);
|
||||
} else {
|
||||
return SL_STATUS_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
sl_button_state_t sl_button_get_state(const sl_button_t *handle)
|
||||
{
|
||||
if (handle->get_state != NULL) {
|
||||
return handle->get_state(handle);
|
||||
} else {
|
||||
return (sl_button_state_t)BUTTON_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
void sl_button_poll_step(const sl_button_t *handle)
|
||||
{
|
||||
if (handle->poll != NULL) {
|
||||
handle->poll(handle);
|
||||
}
|
||||
}
|
||||
|
||||
void sl_button_enable(const sl_button_t *handle)
|
||||
{
|
||||
if (handle->enable != NULL) {
|
||||
handle->enable(handle);
|
||||
}
|
||||
}
|
||||
|
||||
void sl_button_disable(const sl_button_t *handle)
|
||||
{
|
||||
if (handle->disable != NULL) {
|
||||
handle->disable(handle);
|
||||
}
|
||||
}
|
||||
|
||||
SL_WEAK void sl_button_on_change(const sl_button_t *handle)
|
||||
{
|
||||
(void)handle;
|
||||
}
|
||||
205
Libs/platform/driver/button/src/sl_simple_button.c
Normal file
205
Libs/platform/driver/button/src/sl_simple_button.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Simple Button Driver
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_simple_button.h"
|
||||
#include "sl_simple_button_config.h"
|
||||
#include "sl_clock_manager.h"
|
||||
|
||||
#if (SL_SIMPLE_BUTTON_DEBOUNCE_BITS < 1U)
|
||||
#undef SL_SIMPLE_BUTTON_DEBOUNCE_BITS
|
||||
#define SL_SIMPLE_BUTTON_DEBOUNCE_BITS 1U
|
||||
#endif
|
||||
#if (SL_SIMPLE_BUTTON_DEBOUNCE_BITS > 15U)
|
||||
#undef SL_SIMPLE_BUTTON_DEBOUNCE_BITS
|
||||
#define SL_SIMPLE_BUTTON_DEBOUNCE_BITS 15U
|
||||
#endif
|
||||
|
||||
static const uint16_t check_press = (uint16_t)(0xffff << SL_SIMPLE_BUTTON_DEBOUNCE_BITS);
|
||||
static const uint16_t check_release = (uint16_t)(~(0x1 << SL_SIMPLE_BUTTON_DEBOUNCE_BITS));
|
||||
static const uint16_t debounce_window = (uint16_t)(0xffff << (SL_SIMPLE_BUTTON_DEBOUNCE_BITS + 1));
|
||||
|
||||
/***************************************************************************//**
|
||||
* An internal callback called in interrupt context whenever a button changes
|
||||
* its state. (mode - SL_SIMPLE_BUTTON_MODE_INTERRUPT)
|
||||
*
|
||||
* @note The button state is updated by this function. The application callback
|
||||
* should not update it again.
|
||||
*
|
||||
* @param[in] interrupt_no Interrupt number (pin number)
|
||||
* @param[in] ctx Pointer to button handle
|
||||
******************************************************************************/
|
||||
static void sli_simple_button_on_change(uint8_t interrupt_no, void *ctx)
|
||||
{
|
||||
(void)interrupt_no;
|
||||
sl_button_t *button = (sl_button_t *)ctx;
|
||||
sl_simple_button_context_t *simple_button = button->context;
|
||||
sl_gpio_t gpio = {
|
||||
.port = simple_button->port,
|
||||
.pin = simple_button->pin
|
||||
};
|
||||
bool pin_value;
|
||||
|
||||
if (simple_button->state != SL_SIMPLE_BUTTON_DISABLED) {
|
||||
sl_gpio_get_pin_input(&gpio, &pin_value);
|
||||
simple_button->state = ((bool)pin_value == SL_SIMPLE_BUTTON_POLARITY);
|
||||
|
||||
sl_button_on_change(button);
|
||||
}
|
||||
}
|
||||
|
||||
sl_status_t sl_simple_button_init(const sl_button_t *handle)
|
||||
{
|
||||
int32_t interrupt_em4, interrupt_ext;
|
||||
sl_status_t status;
|
||||
sl_button_t *button = (sl_button_t *)handle;
|
||||
sl_simple_button_context_t *simple_button = button->context;
|
||||
sl_gpio_t gpio = {
|
||||
.port = simple_button->port,
|
||||
.pin = simple_button->pin
|
||||
};
|
||||
bool pin_value;
|
||||
|
||||
sl_clock_manager_enable_bus_clock(SL_BUS_CLOCK_GPIO);
|
||||
|
||||
sl_gpio_set_pin_mode(&gpio, SL_SIMPLE_BUTTON_GPIO_MODE, SL_SIMPLE_BUTTON_GPIO_DOUT);
|
||||
sl_gpio_get_pin_input(&gpio, &pin_value);
|
||||
simple_button->state = ((bool)pin_value == SL_SIMPLE_BUTTON_POLARITY);
|
||||
|
||||
if (simple_button->mode == SL_SIMPLE_BUTTON_MODE_INTERRUPT) {
|
||||
interrupt_em4 = SL_GPIO_INTERRUPT_UNAVAILABLE;
|
||||
interrupt_ext = SL_GPIO_INTERRUPT_UNAVAILABLE;
|
||||
// Try to register an EM4WU interrupt for the given pin
|
||||
status = sl_gpio_configure_wakeup_em4_interrupt(&gpio,
|
||||
&interrupt_em4,
|
||||
SL_SIMPLE_BUTTON_POLARITY,
|
||||
(sl_gpio_irq_callback_t)sli_simple_button_on_change,
|
||||
button);
|
||||
if (interrupt_em4 == SL_GPIO_INTERRUPT_UNAVAILABLE) {
|
||||
// if the pin not EM4WU-compatible, instead register a regualr interrupt
|
||||
status = sl_gpio_configure_external_interrupt(&gpio,
|
||||
&interrupt_ext,
|
||||
SL_GPIO_INTERRUPT_RISING_FALLING_EDGE,
|
||||
(sl_gpio_irq_callback_t)sli_simple_button_on_change,
|
||||
button);
|
||||
EFM_ASSERT(status == SL_STATUS_OK);
|
||||
} else {
|
||||
// If the pin is EM4WU-compatible, setup the pin as an EM4WU pin
|
||||
// Since EM4WU interrupts are level-sensitive and not edge-sensitive, also register a regular edge-sensitive interrupt to capture the other edge
|
||||
uint8_t flags;
|
||||
if (SL_SIMPLE_BUTTON_POLARITY == 0) {
|
||||
flags = SL_GPIO_INTERRUPT_RISING_EDGE;
|
||||
} else if (SL_SIMPLE_BUTTON_POLARITY == 1) {
|
||||
flags = SL_GPIO_INTERRUPT_FALLING_EDGE;
|
||||
}
|
||||
status = sl_gpio_configure_external_interrupt(&gpio,
|
||||
&interrupt_ext,
|
||||
flags,
|
||||
(sl_gpio_irq_callback_t)sli_simple_button_on_change,
|
||||
button);
|
||||
EFM_ASSERT(status == SL_STATUS_OK);
|
||||
}
|
||||
}
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
sl_button_state_t sl_simple_button_get_state(const sl_button_t *handle)
|
||||
{
|
||||
sl_button_t *button = (sl_button_t *)handle;
|
||||
sl_simple_button_context_t *simple_button = button->context;
|
||||
|
||||
return simple_button->state;
|
||||
}
|
||||
|
||||
void sl_simple_button_poll_step(const sl_button_t *handle)
|
||||
{
|
||||
sl_button_t *button = (sl_button_t *)handle;
|
||||
sl_simple_button_context_t *simple_button = button->context;
|
||||
bool button_press, pin_value;
|
||||
sl_gpio_t gpio = {
|
||||
.port = simple_button->port,
|
||||
.pin = simple_button->pin
|
||||
};
|
||||
|
||||
if (simple_button->state == SL_SIMPLE_BUTTON_DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
sl_gpio_get_pin_input(&gpio, &pin_value);
|
||||
button_press = (bool)pin_value;
|
||||
|
||||
if (simple_button->mode == SL_SIMPLE_BUTTON_MODE_POLL_AND_DEBOUNCE) {
|
||||
uint16_t history = simple_button->history;
|
||||
history = (history << 1) | (button_press ^ SL_SIMPLE_BUTTON_POLARITY) | (debounce_window);
|
||||
|
||||
if (history == check_press) {
|
||||
simple_button->state = SL_SIMPLE_BUTTON_PRESSED;
|
||||
}
|
||||
if (history == check_release) {
|
||||
simple_button->state = SL_SIMPLE_BUTTON_RELEASED;
|
||||
}
|
||||
|
||||
simple_button->history = history;
|
||||
} else if (simple_button->mode == SL_SIMPLE_BUTTON_MODE_POLL) {
|
||||
simple_button->state = (button_press == SL_SIMPLE_BUTTON_POLARITY);
|
||||
}
|
||||
}
|
||||
|
||||
void sl_simple_button_enable(const sl_button_t *handle)
|
||||
{
|
||||
sl_button_t *button = (sl_button_t *)handle;
|
||||
sl_simple_button_context_t *simple_button = button->context;
|
||||
|
||||
// Return if the button is not disabled
|
||||
if (simple_button->state != SL_SIMPLE_BUTTON_DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear history
|
||||
simple_button->history = 0;
|
||||
// Reinit button
|
||||
sl_simple_button_init(handle);
|
||||
}
|
||||
|
||||
void sl_simple_button_disable(const sl_button_t *handle)
|
||||
{
|
||||
sl_button_t *button = (sl_button_t *)handle;
|
||||
sl_simple_button_context_t *simple_button = button->context;
|
||||
|
||||
// Return if the button is disabled
|
||||
if (simple_button->state == SL_SIMPLE_BUTTON_DISABLED) {
|
||||
return;
|
||||
}
|
||||
if (simple_button->mode == SL_SIMPLE_BUTTON_MODE_INTERRUPT) {
|
||||
sl_gpio_deconfigure_external_interrupt(simple_button->pin);
|
||||
}
|
||||
// Disable the button
|
||||
simple_button->state = SL_SIMPLE_BUTTON_DISABLED;
|
||||
}
|
||||
Reference in New Issue
Block a user